当 $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

查看:24
本文介绍了当 $state.go 调用 $stateChangeStart 时,Angular 1.4.1 UI 路由器 10 $digest() 迭代的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个需要授权的状态.我监听 $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.protectedand 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:

  1. 拦截到 main.submain 状态的转换
  2. 开始转换到登录状态
  3. UI 路由器获取第一次转换被取消的信息
  4. UI 路由器运行 $urlRouter.update() 并开始转换到 main.submain
  1. Intercept the transition to main.submain state
  2. Start transition to login state
  3. UI router gets the information that the first transiotion got cancelled
  4. 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屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆