我在角度应用程序中使用ui-router。目前我有两条路线/登录& /用户。 最初它在用户点击登录按钮时显示/登录,我发送ajax请求并获取用户ID。我将用户ID存储在localstorage中,并将状态更改为/ user。
现在,我想要的是,如果用户没有登录,并且用户将地址栏更改为/ user,则不会更改视图,而是会将地址栏网址更改为/ signin。
我尝试使用解决方案,但它不起作用。我的代码是: -
module.exports = function($stateProvider, $injector) {
$stateProvider
.state('signin', {
url: '/signin',
template: require('../templates/signin.html'),
controller: 'LoginController'
})
.state('user', {
url: '/user/:id',
template: require('../templates/user.html'),
resolve:{
checkLogin: function(){
var $state = $injector.get('$state');
console.log("in resolve");
if (! window.localStorage.getItem('user-id')) {
console.log("in if")
$state.go('signin');
}
}
},
controller: 'UserController'
})
}
请帮我解决这个问题。
答案 0 :(得分:10)
我认为不允许在状态转换过程中改变状态。
因此,解决它的方法是让checkLogin
resolve参数(我将其更改为userId
)成为一个返回值或promise的函数(在这种情况下,如果您无法获得user-id
),则拒绝承诺。
然后,您需要在$rootScope.$on('$stateChangeError')
中处理此问题并检查错误代码。
resolve: {
userId: function ($q, $window) {
var userId = $window.localStorage.getItem('user-id');
if (!userId) {
return $q.reject("signin")
}
return userId;
}
}
并在$stateChangeError
处理程序中重定向:
$rootScope.$on('$stateChangeError', function (event, toState, toParams, fromState, fromParams, error) {
if (error === "signin") {
$state.go("signin");
}
});
答案 1 :(得分:2)
如果有人遇到此问题,您可以使用超时服务解决此问题。它将把状态切换调用放在队列的末尾。
另外,你应该使用promises。拒绝它将阻止该状态的初始化:
resolve:{
checkLogin: function(){
var deferred = $q.defer();
var $state = $injector.get('$state');
if (!window.localStorage.getItem('user-id')) {
$timeout(function(){$state.go('signin');});
deferred.reject();
} else {
deferred.resolve();
}
return deferred.promise;
}
},