AngularJS ui router $stateChangeStart with promise无限循环
AngularJS ui router $stateChangeStart with promise inifinite loop
我试图在我的angular应用程序中建立某种身份验证,并希望在用户未登录时重定向到外部URL(基于$http.get)。
当event.preventDefault()是$stateChangeStart的第一行时,我最终陷入了一个无限循环。
我在stackoverflow上看到过多个问题的答案,比如"将event.preventDefault()放在状态之前。进入else"。但是随后控制器被触发,并且在promise返回之前页面已经显示。
即使我将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:
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;
});
}
EDIT:添加状态:
$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';
}
});
}
}
});
});
通过从函数返回一个promise, ui-router在promise被解析之前不会初始化状态。
如果你有其他或子状态需要等待这个,你需要注入auth
。
来自维基:
如果你想在实例化子节点之前等待承诺被解析,那么必须将解析键注入子节点状态。
相关文章:
- 使用promise和mongoose对文档进行排序
- Fighting with FRP
- issue with FB.Event.subscribe
- 测试Angular Service解决错误回调中的promise
- geolocation-marker.js conflict with markerclusterer.js
- Angular 2.0 with JavaScript or TypeScript?
- javascript singleton with promise
- Promise/A+ with chain then() 回调用例
- 如何在 Node JS FS 模块中使用 Typescript Async/ await with promise
- Chained Promise with Express:在最后一步中未收到任何数据
- Promise.all behavior with RxJS Observables?
- Jasmine Testing with Angular Promise 无法使用 TypeScript 解析
- NodeJS:在循环中使用 Promise with Q
- Javascript Q Promise Sequence Order with Arguments
- angularjs ng-show with promise expression
- Coffeescript Promise with Jquery Post
- AngularJS ui router $stateChangeStart with promise无限循环
- undefined with promise async / await
- ' fetch ', work with mode ' no-cors '不会调用promise.然后回调
- $resource angular returning undefined with $promise