情况是,我在(run)上有事件。该事件根据REST请求响应状态代码更改$rootScope.authenticated的值。
但是,当事件被触发时,我试图在我的控制器中将$rootScope.authenticated的值打印到控制台,它说它是“未定义的”值。
角跑:
pos.run(function($rootScope,$log,apiService){
// register event
$rootScope.$on('$routeChangeSuccess', function () {
// call api function
apiService.is_authenticated().then(
function(response){
if(response.status == "AUTHENTICATED"){
$rootScope.authenticated = true;
}else if(response.status == "NOT_AUTHENTICATED"){
$rootScope.authenticated = false;
}
});
})
});
控制器:
// controller
pos.controller('TestController', function($rootScope,$scope,$http) {
console.log($rootScope.authenticated);
});
它应该打印“真”或“假”。我知道它在控件执行后分配值,但是如何将控制器的执行延迟到指定的值为止?
发布于 2016-02-02 07:56:04
事实是,如果使用$promise模式,就永远无法保证执行的顺序,因为它是异步的,或者有足够的“安全”延迟。
你可能想换别的地方,一种方法是让它同步:
if (apiService.is_authenticated()){
$rootScope.authenticated = true;
}
另一种方法是让$broadcast或$emit再次在“运行”中听一听。
$rootScope.$on("LOGIN_SUCCESSFUL", function () {
$rootScope.authenticated = true;
});
你可以合并到$watch
或者使用http拦截器
有很多种方式,但这取决于你!
发布于 2016-02-02 08:07:48
最近研究了同样的解决方案,并在这里阅读了很多答案。其实有很多要找的,但没有一个被接受的答案对我有效。我找到了一个适用于最新ui路由器的解决方案,但它不被接受:
它是在preventDefault事件上调用一个stateChangeStart,然后您就可以完成您的承诺了。如果成功,则设置一个旁路标志,并再次转换到相同的状态,但由于旁路标志,它跳过了允诺/解决部分:
$rootScope.$on('$stateChangeStart', function (event, toState, toParams) {
if($rootScope.stateChangeBypass || toState.name === 'login') {
$rootScope.stateChangeBypass = false;
return;
}
event.preventDefault();
Auth.getCurrentUser().then(function(user) {
if (user) {
$rootScope.stateChangeBypass = true;
$state.go(toState, toParams);
} else {
$state.go('login');
}
});
});
摘自:https://stackoverflow.com/a/28827077/2019281
我目前正在处理的另一个选项是使用根状态定义的解析对象。解决是完美的,因为它将阻止控制器初始化,直到承诺被解决或拒绝。您可以在拒绝时抛出一个错误,您可以在应用程序的run方法中捕获该错误:
国家定义:
$stateProvider.state('admin', {
'url': '/admin',
'controller': 'adminController',
'templateUrl': 'admin.html'
'resolve': {
'auth': [
'$q', 'Auth',
function ($q, Auth) {
return Auth.getCurrentUser().then(
function resolved (user) {
return (user) ? user : $q.reject('authRejected');
},
function rejected (user) {
return $q.reject('authRejected');
}
});
}
]
}
});
App的运行方法:
$rootScope.$on('$stateChangeError', function (e, toState, toParams, fromState, fromParams, error) {
if (error === 'authRejected') {
$state.go('login');
}
});
缺点是,您需要将根状态添加到要保护的状态,或者将该解决方案添加到要保护的每个状态。此外,您将始终需要在状态器上使用reload: true
,以便在每个状态集上重新加载解决方案。
https://stackoverflow.com/questions/35155678
复制