我知道通常你不想这样做,但是我找到了一个用例,我似乎无法找到任何其他解决方案,并希望我的函数包含一个承诺,等到承诺结算在回国之前。
我正在修改应用程序的身份验证机制,并设置以下代码,以便在$状态更改时仔细检查用户是否已获得授权,如果未经授权,则将其重定向回登录屏幕:
$rootScope.$on('$stateChangeStart', function (event, toState, toParams, fromState, fromParams) {
// double check that the user is logged in
if (toState && toState.name.indexOf('auth')<0) {
if (!user.isAuthorized()) {
event.preventDefault(); // do not continue to the non-auth state
user.logout();
$state.go("auth.login");
}
}
});
目前,user.isAuthorized()函数只是从用户登录或注销时设置/取消设置的内部布尔值返回true或false值,并且一切正常。
但是,我们需要将该函数调用到服务器(如果本地布尔值设置为false)以检查用户是否已经有活动会话,然后设置布尔值并返回true。在服务器调用返回之前,我们不希望应用程序执行任何操作,因为它正在检查用户是否应该能够看到UI。
我试图利用一个承诺来处理这种情况,但它有意想不到的结果,因为event.preventDefault()调用没有被立即调用(只有在promise解析之后),此时$ state已经改变。这至少导致UI在被发送到登录屏幕之前短暂闪烁,并且在某些情况下,那些其他$状态在加载时自己进行服务器调用失败和/或导致浏览器提示用户进行基本授权(用户名) /密码)。
这不起作用:
$rootScope.$on('$stateChangeStart', function (event, toState, toParams, fromState, fromParams) {
// double check that the user is logged in
if (toState && toState.name.indexOf('auth')<0) {
user.isAuthorized().then(function(isAuthorized) {
if (!isAuthorized()) {
event.preventDefault(); // this does not prevent state change any more
user.logout();
$state.go("auth.login");
}
});
}
});
我认为我们需要让user.isAuthorized()函数看起来像这样:
user.isAuthorized = function() {
if(user.isAuthorizedBoolean) {
return true;
} else {
var returnValue = false;
// make server side call that returns promise
user.isAuthorizedServerCheck().then(function(result) {
if (result === true) {
returnValue = true;
}
});
// pause execution until promise resolves???
return returnValue;
}
};
但我不确定如何做到这一点。
答案 0 :(得分:0)
看起来像这里发布的解决方案:@ {RadimKöhlerConfusing $locationChangeSuccess and $stateChangeStart正是我正在寻找的。 p>