Angularjs 在状态更改之前解析承诺
我正在使用ui路由器和ui路由器附加程序Angularjs 在状态更改之前解析承诺,angularjs,angular-ui-router,angular-ui-router-extras,Angularjs,Angular Ui Router,Angular Ui Router Extras,我正在使用ui路由器和ui路由器附加程序 $scope.$on('$transitionStart', function (e, $transition$) { var params = {id:1}; factory.webService(params) .success(function (data) { if (data.d == "Expired") {//Inspects the application session
$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帮助。是的,有更优雅的方法: 例如:
$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) : [];
}
}
});
有关更多详细信息,请阅读以下文章
我需要等待$http响应并在.success
函数中捕获它
.success
方法不能拒绝承诺,但方法可以将成功转换为拒绝:
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
方法解析的响应创建新的派生承诺
当ui路由器状态的解析器函数获得拒绝的承诺时,状态更改将中止
更新
所以我有这样的代码
//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
时成功
//CORRECT
})
.catch(function (response) {
//THROW to chain rejection
throw response;
//e.preventDefault();
});
而且.catch
方法是错误的
当.catch
方法的拒绝处理程序忽略return
(或throw
)语句时,函数返回undefined
的值。这将把拒绝转换为一个成功的承诺,该承诺的值为undefined
//CORRECT
})
.catch(function (response) {
//THROW to chain rejection
throw response;
//e.preventDefault();
});
函数式编程的经验法则是--总是返回一些东西
在承诺成功和拒绝的情况下:始终返回
或抛出
某物。我忘了提到,工厂返回$http,因此我需要等待$http响应,并在成功函数中捕获它,可能我不理解page@ChildGG,只需将工厂注入解析对象中的一些数据
,如示例中的UserService
。之后,只需返回您在问题中分配给PROMITE变量的相同实现。@ChildGG很乐意提供帮助。如果有帮助,请投票并接受我的答案。干杯你好,georgeawg,多亏了Tome和你,我在状态更改之前获得了响应,但现在我不明白为什么抛出没有触发$stateChangeErrorResolver函数没有返回派生的承诺。见补充答案。