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

问题描述

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').

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.

Uncaught Error: [$rootScope:infdig] 10 $digest() iterations reached. Aborting!

See this plnkr: http://plnkr.co/edit/1voh7m?p=preview

I successfully use similar code in different project with angular 1.2.26 with no errors.

Example code 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. 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

EDIT: Simplified state configuration.

解决方案

This is an issue of the UI.Router – see this issue on Github: https://github.com/angular-ui/ui-router/issues/600

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');
});

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.

Working plunk: http://plnkr.co/edit/eQXaIk

这篇关于当 $state.go 在 $stateChangeStart 上调用时,Angular 1.4.1 UI Router 10 $digest() 迭代的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-06 14:51