当 $state.go 调用 $stateChangeStart 时,Angular 1.4.1 UI 路由器 10 $digest() 迭代 [英] Angular 1.4.1 UI Router 10 $digest() iterations when $state.go called on $stateChangeStart
问题描述
我有一个需要授权的状态.我监听 $stateChangeStart
事件,如果 toState.data.protected
和用户没有被授权我调用 e.preventDefault()
和$state.go('login')
.
I have a state that requires authorization. I listen to the $stateChangeStart
event and if the toState.data.protected
and the user is not authorized I call e.preventDefault()
and $state.go('login')
.
当我在根 url 中打开应用程序时,我会自动重定向到受保护状态.这会导致 10 个 $digest 循环,当我在根 url 中打开应用程序时,我最终处于登录状态,并且我会自动重定向到受保护状态.
When I open the app in root url I'm automatically redirected to protected state. This causes 10 $digest loops and I end up in the login state when I open the app in the root url and I'm automatically redirected to a protected state.
未捕获的错误:[$rootScope:infdig] 已达到 10 个 $digest() 迭代.中止!
看到这个 plnkr:http://plnkr.co/edit/1voh7m?p=preview
See this plnkr: http://plnkr.co/edit/1voh7m?p=preview
我在不同的项目中成功使用了类似的代码,角度为 1.2.26,没有错误.
I successfully use similar code in different project with angular 1.2.26 with no errors.
示例代码angular 1.4.1, ui.router 0.2.15
:
//config block
$urlRouterProvider.otherwise('/main');
$stateProvider
.state('main', {
url: '/main',
templateUrl: 'main.html',
controller: 'MainController as main',
data: {'protected': true}
})
.state('login', {
url: '/login',
templateUrl: 'login.html',
controller: 'LoginController as login'
});
// in a run block
$rootScope.$on("$stateChangeStart", function (event, toState) {
if (!event.defaultPrevented && toState.data &&
toState.data.protected) {
// the user is not authorized, do not switch to state
event.preventDefault();
// go to login page
$state.go('login');
}
});
你知道是什么导致了循环吗?
Do you know what causes the loop?
我想知道事情是否会像这样发生:
I wonder if the things might be happening like this:
- 拦截到 main.submain 状态的转换
- 开始转换到登录状态
- UI 路由器获取第一次转换被取消的信息
- UI 路由器运行
$urlRouter.update()
并开始转换到 main.submain
- Intercept the transition to main.submain state
- Start transition to login state
- UI router gets the information that the first transiotion got cancelled
- UI router runs
$urlRouter.update()
and starts transition to main.submain
简化的状态配置.
推荐答案
这是 UI.Router 的问题 – 在 Github 上查看此问题:https://github.com/angular-ui/ui-router/issues/600
This is an issue of the UI.Router – see this issue on Github: https://github.com/angular-ui/ui-router/issues/600
基本上,如果您使用 .otherwise('/main')
(也由@Grundy 指出),那么当路径无法访问时,url 将更改为 /main
得到解决.在 $locationChangeSuccess
之后,我的监听器被调用,我使用 event.preventDefault()
拒绝重定向.这会导致位置变回未知路径,从而导致再次使用回退路径.这会导致无限循环.解决办法是这样的:
Basically, if you use .otherwise('/main')
(also pointed out by @Grundy) then the url is changed to /main
when the path cannot be resolved. After $locationChangeSuccess
my listener is called and I reject the redirection using event.preventDefault()
. This causes the location to change back to the unknown path thus causing the fallback path to be used again. This causes the infinite loop. The solution is this:
$urlRouterProvider.otherwise(function($injector) {
var $state = $injector.get('$state');
$state.go('main');
});
您可以声明一个使用 $injector
调用的函数,并且您可以重定向到您的主状态(或 404),而无需来回更改位置.感谢 Github 上的人,我应该在发布这个问题之前在那里搜索.
You can state a function which gets called with $injector
and you can redirect to your main state (or 404) without back-and-forth location changes. Thx to the guys on Github, I should have searched there before posting this question.
工作 plunk:http://plnkr.co/edit/eQXaIk
这篇关于当 $state.go 调用 $stateChangeStart 时,Angular 1.4.1 UI 路由器 10 $digest() 迭代的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!