我正在使用ui-router和ui-router extras
$scope.$on('$transitionStart', function (e, $transition$) {
var params = {id:1};
factory.webService(params)
.success(function (data) {
if (data.d == "Expired") {//Inspects the application session
//Stops the state request and sents you to the login screen
e.preventDefault();
location.href = "login.html";
}
else if (data.d == "NotAllowed") {
//Stops the state request and keeps you on the state you already are
e.preventDefault();
} else {
//Proceed to load the requested state
}
})
.error(function (data, status) {
alert(data.Message);
});
});
我需要在加载$ stateChangeStart之前解决成功部分,并且无法弄清楚如何做到这一点。
有没有办法实现这个目标?
修改
所以我的代码就像这样
.state('myState', {
url: "/myState",
templateUrl: 'views/template.html',
controller: 'ctrlTemplate',
viewId: 99,
resolve: {
fn: function ($stateParams, myFactory) {
myFactory.checkSession({viewId:99})
.then(function onSuccess(response) {
var data = response.data;
if (data.d == "Expired") {
throw "Expired";
}
else if (data.d == "NotAllowed") {
throw "NotAllowed";
} else {
//RETURN to chain data
return data;
//Proceed to load the requested state
}
})
.catch(function (response) {
//e.preventDefault();
});
}
}
})
$ http .then
函数仍然在$stateChangeStart
$transitionStart
发生后解析,并且新状态已经加载。我可以在浏览器控制台调试器中看到它发生了
Plz帮助。
答案 0 :(得分:1)
是的,有更优雅的方式:resolve by ui-router
示例:
$stateProvider.state('users.profile', {
url: '/:id',
templateUrl: 'views/users.profile.html',
controller: 'UsersController',
resolve: {
user: function($stateParams, UserService) {
return UserService.find($stateParams.id);
},
tasks: function(TaskService, user) {
return user.canHaveTasks() ?
TaskService.find(user.id) : [];
}
}
});
请阅读Advanced routing and resolves上的以下文章了解更多详情。
答案 1 :(得分:1)
我需要等待$ http响应并在
上捕获它.success
函数
.success
方法(deprecated and now removed from AngularJS 1.6)无法拒绝承诺,但.then
方法能够将成功转化为拒绝:
var promise = factory.webService(params)
//.success(function (data) {
.then( function onSuccess(response) {
var data = response.data;
if (data.d == "Expired") {
//THROW to create a rejected promise
throw "Expired";
/*
//Inspects the application session
//Stops the state request and sents you to the login screen
e.preventDefault();
location.href = "login.html";
*/
}
else if (data.d == "NotAllowed") {
//THROW to create a rejected promise
throw "NotAllowed";
/*
//Stops the state request and keeps you on the state you already are
e.preventDefault();
*/
} else {
//RETURN to chain data
return data;
//Proceed to load the requested state
}
})
//.error(function onError(data, status) {
.catch( function(response) {
var data = response.data;
var status = response.status;
alert(data.Message);
//THROW to chain rejection
throw data.Message;
});
});
通过使用return
或throw
语句,可以从httpPromise的.then
或.catch
方法解析的响应中创建新的派生承诺。 / p>
当ui-router状态的解析器功能被拒绝时,状态更改将中止。
所以我的代码就是这样......
//ERRONEOUS resolve: { fn: function ($stateParams, myFactory) { myFactory.checkSession({viewId:99}) .then(function onSuccess(response) { var data = response.data; if (data.d == "Expired") { throw "Expired"; }
我无法理解为什么投掷不会触发$ stateChangeError。
解析器功能需要返回对路由器的承诺:
resolve: {
fn: function ($stateParams, myFactory) {
//vvvvvv RETURN the promise
return myFactory.checkSession({viewId:99})
.then(function onSuccess(response) {
var data = response.data;
if (data.d == "Expired") {
throw "Expired";
}
当函数省略return
语句时,函数返回值undefined
。在这种情况下,路由器认为它成功,值为undefined
。
.catch
方法也是错误的
//ERRONEOUS }) .catch(function (response) { //e.preventDefault(); });
当.catch
方法的拒绝处理程序省略return
(或throw
)语句时,该函数返回值undefined
。这会将转换拒绝转换为以undefined
值解析的成功承诺。
//CORRECT
})
.catch(function (response) {
//THROW to chain rejection
throw response;
//e.preventDefault();
});
功能编程的经验法则是 - 总是返回。
在承诺成功和拒绝的情况下:始终return
或throw
。