gpt4 book ai didi

javascript - AngularJS ui 路由器 $stateChangeStart 带有 promise 无限循环

转载 作者:行者123 更新时间:2023-11-27 23:49:04 26 4
gpt4 key购买 nike

我正在尝试在我的 Angular 应用程序中构建某种身份验证,并希望在用户未登录时重定向到外部 URL(基于 $http.get)。

当 event.preventDefault() 是 $stateChangeStart 中的第一行时,不知怎的,我最终陷入了无限循环。

我在 stackoverflow 上看到了多个问题的答案,比如“将 event.preventDefault() 放在 else 中的 state.go 之前”。但随后 Controller 被触发,并且在返回 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 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 不会等待您的 Promise 解决后再退出。让状态等待 Promise 的唯一方法是在状态选项中使用 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 得到解决之前不会初始化状态。

如果您有其他状态或子状态需要等待此操作,则需要注入(inject)auth

来自wiki :

The resolve keys MUST be injected into the child states if you want to wait for the promises to be resolved before instantiating the children.

关于javascript - AngularJS ui 路由器 $stateChangeStart 带有 promise 无限循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32871647/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com