Ui-Router $state.go inside $on('$stateChangeStart') is cauzing an infinite loop

前端 未结 6 1797
南方客
南方客 2020-12-03 10:52

I\'m trying to introduce login into the way the user navigates accross the application.

I pretend to redirect the user to the page were he was before he navigate to

相关标签:
6条回答
  • 2020-12-03 11:25

    In general I would say, let's redirect ($state.go()) only if needed. In other cases, get out from the event listener:

    if (toState.name === 'login' ){
      // doe she/he try to go to login? - let him/her go
      return;
    }
    
    if(Auth.isLoggedIn()){
       // is logged in? - can go anyhwere
       return;
    }
    
    // else
    $state.go('login')
    

    This is simplified logic, but shows, that we should change to execution only if needed. There are some other examles with more detailed implementation and plunkers:

    • Confusing $locationChangeSuccess and $stateChangeStart
    • Angular UI Router: nested states for home to differentiate logged in and logged out
    • other example of log in
    • angular ui-router login authentication

    As provided in the comment, there was plunker, which I changed like this here

    ...
    // three new lines
    if (toState.name === 'specialRoute'){
      return;
    }
    
    if (fromState.name=='route1'){
      event.preventDefault();
      $state.go('specialRoute')
    }
    

    And this is not looping anymore. Please, check it here

    0 讨论(0)
  • 2020-12-03 11:34

    You should use the notify option :

    $state.go('your.state',{ your params },{notify: false});
    

    This will prevent stateChangeStart to fire again.

    0 讨论(0)
  • 2020-12-03 11:39

    It works for me, Below code helps to get rid of infinite loop

      let firstPass = true;
      $scope.$on('$stateChangeStart', function(event, toState, toParams) {
        if ($scope.addForm.$dirty && firstPass) {
          event.preventDefault();
          ConfirmationDialog.openNavigateAwayConfirmationModal().then(function () {
            firstPass = false;
            return $state.go(toState, toParams);
          });
          firstPass = true;
        }
      });
    
    0 讨论(0)
  • 2020-12-03 11:44

    This answer helped me:

    $urlRouterProvider.otherwise( function($injector, $location) {
                var $state = $injector.get("$state");
                $state.go("app.home");
            });
    

    Original: Why does AngularJS with ui-router keep firing the $stateChangeStart event?

    0 讨论(0)
  • 2020-12-03 11:45

    The infinite loop is partly caused by

    if (toState.name == 'login' ...) { $state.go('login'); ...
    

    ..which says if you're going to the login state, then go to the login state.

    ...And calling event.preventDefault() as the first line in the event handler doesn't help. When you use go() to go to the login screen (or anywhere else), that state change is also prevented by event.preventDefault(). It should only be used within an if.

    Your entire $stateChangeStart handler should instead be...

    if (!Auth.isLoggedIn() && toState.name != 'login') {
        event.preventDefault();
        Auth.desiredState = toState.name;
        $state.go('login');
    }
    

    ...which reads naturally. "If you're not logged in and you're not already going to the login screen, then stop what you're doing, I'll remember where you wanted to go, and you now go to the login screen."

    Later your Auth object will issue a $state.go(Auth.desiredState) when it's satisfied with the user.

    0 讨论(0)
  • 2020-12-03 11:46

    I simply used $location.path('every/where') instead of $state.go('every/where')

    :) .

    0 讨论(0)
提交回复
热议问题