web-dev-qa-db-fra.com

Ui-Router $ state.go inside $ on ('$ stateChangeStart') déclenche une boucle infinie

J'essaie d'introduire la connexion dans la façon dont l'utilisateur navigue dans l'application.

Je fais semblant de rediriger l'utilisateur vers la page où il se trouvait avant de naviguer vers la page de connexion si cette page répond à des exigences spécifiques

Empêcher l’événement de $ stateChangeStart d’arrêter le changement d’état comme prévu, mais lorsque je lance le $ state.go ('into_somewhere'), j’entre dans une boucle infinit

Ma version angulaire est 1.3.1 et le routeur ui est le dernier

.factory('RouteHistory', function ($rootScope,$log, $state, Auth, $urlRouter, $timeout) {

    // after the user enter a page
    var currentState = '';

    // when the user is trying to access a page that he has not permissions
    // or that requires the user to be logged in
    var pendingState = '';

    var isMenuTogglerVisible = false;
    var skipFromStateVal = true;

    $rootScope.$on('$stateChangeStart', function(event, toState, toParams, fromState, fromParams){

      event.preventDefault();



      if (toState.name == 'login' && fromState.name != 'login'){
        $log.log('Ui-router: changing to login');
        // $urlRouter.sync();
        $state.go('login')
        //pendingState = fromState;
        //$log.log('Peding state updated to:' + pendingState.name );
        //$urlRouter.sync();
      }

      if (fromState.name == 'login' && Auth.isLoggedIn()) {
        $log.log('Ui-router: going from login');
        //$state.go(fromState.name);
        $timeout(function(){
          // $state.go('home', null, {/*reload: true, location: 'replace'*/});
          $state.go('browse-machine');
          //$urlRouter.sync();
        },2000)
      }



      $log.log({
        'toState': toState,
        'toParams': toParams,
        'fromState': fromState,
        'fromParams': fromParams
      })

    })


    return {

    };
  });
16
Lothre1

Vous devriez utiliser l'option notify:

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

Cela empêchera stateChangeStart de se déclencher à nouveau.

8
Rémy DAVID

Cette réponse m'a aidé:

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

Original: Pourquoi AngularJS avec ui-router continue de déclencher l'événement $ stateChangeStart?

6
Andi Giga

Cela fonctionne pour moi, le code ci-dessous aide à se débarrasser de la boucle infinie

  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;
    }
  });
1
user3741852

La boucle infinie est en partie causée par 

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

..qui dit if vous allez à l'état de connexion, then allez à l'état de connexion.

... Et appeler event.preventDefault() en tant que première ligne du gestionnaire d'événements n'aide pas. Lorsque vous utilisez go() pour accéder à l'écran de connexion (ou ailleurs), ce changement d'état est également empêché par event.preventDefault(). Il ne devrait être utilisé que dans une if.

Votre gestionnaire $ stateChangeStart entier devrait plutôt être ... 

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

... qui se lit naturellement. "If tu n'es pas connecté et tu ne vas pas déjà à l'écran de connexion, then arrête ce que tu fais, je me souviendrai où tu voulais aller, et tu vas maintenant à l'écran de connexion."

Plus tard, votre objet Auth émettra une $state.go(Auth.desiredState) lorsqu'il sera satisfait de l'utilisateur.

1
Ron Newcomb

J'ai simplement utilisé $location.path('every/where') au lieu de $state.go('every/where')

:).

1
ivahidmontazer