我正在尝试在我的角度应用程序中构建某种身份验证,并希望在用户未登录(基于$ http.get)时重定向到外部URL。
当event.preventDefault()是$ stateChangeStart的第一行时,不知何故,我最终陷入了无限循环。
我已经看到了关于stackoverflow答案的多个问题,比如说“将event.preventDefault()放在else的state.go之前”。但是随后控制器被解雇,并且在返回诺言之前已经显示了该页面。
即使我将event.preventDefault()放在else中,也会发生奇怪的事情:
转到根URL,它将在URL和$ stateChangeStart多次触发后自动添加/#/。
app.js运行部分:
.run(['$rootScope', '$window', '$state', 'authentication', function ($rootScope, $window, $state, authentication) {
$rootScope.$on('$stateChangeStart', function (event, toState, toParams) {
event.preventDefault();
authentication.identity()
.then(function (identity) {
if (!authentication.isAuthenticated()) {
$window.location.href = 'external URL';
return;
} else {
$state.go(toState, toParams);
}
});
});
}]);
authentication.factory.js identity()函数:
function getIdentity() {
if (_identity) {
_authenticated = true;
deferred.resolve(_identity);
return deferred.promise;
}
return $http.get('URL')
.then(function (identity) {
_authenticated = true;
_identity = identity;
return _identity;
}, function () {
_authenticated = false;
});
}
编辑:添加状态:
$stateProvider
.state('site', {
url: '',
abstract: true,
views: {
'feeds': {
templateUrl: 'partials/feeds.html',
controller: 'userFeedsController as userFeedsCtrl'
}
},
resolve: ['$window', 'authentication', function ($window, authentication) {
authentication.identity()
.then(function (identity) {
if (!authentication.isAuthenticated()) {
$window.location.href = 'external URL';
}
})
}]
})
.state('site.start', {
url: '/',
views: {
'container@': {
templateUrl: 'partials/start.html'
}
}
})
.state('site.itemList', {
url: '/feed/{feedId}',
views: {
'container@': {
templateUrl: 'partials/item-list.html',
controller: 'itemListController as itemListCtrl'
}
}
})
.state('site.itemDetails', {
url: '/items/{itemId}',
views: {
'container@': {
templateUrl: 'partials/item-details.html',
controller: 'itemsController as itemsCtrl'
}
}
})
}])
如果您需要更多信息,或者需要更多来自app.js的代码,请告诉我!
最佳答案
$stateChangeStart
在退出之前不会等待您的承诺得到解决。使状态等待承诺的唯一方法是在状态选项中使用resolve
。
.config(function($stateProvider) {
$stateProvider.state('home', {
url: '/',
resolve: {
auth: function($window, authentication) {
return authentication.identity().then(function (identity) {
if (!authentication.isAuthenticated()) {
$window.location.href = 'external URL';
}
});
}
}
});
});
通过从函数返回一个承诺,ui-router在该承诺解决之前不会初始化状态。
如果您有其他状态或子状态需要等待,则需要插入
auth
。从wiki:
如果您要在实例化子项之前等待promise的解决,则必须将resolve键注入子状态。