web-dev-qa-db-fra.com

Comment rediriger dans une résolution de routeur ui?

J'essaie de rediriger à l'intérieur d'une résolution de routeur ui et je voulais savoir s'il existe un moyen de rediriger un résolveur de routeur. Actuellement, cela ne fonctionne pas comme on pourrait le penser.

resolver(auth, $state){
   if(!auth.isLoggedIn()){
       $state.go('noLoggedInPath');
   }
}

Comment on redirige dans un résolveur correctement?

Mon temp hack est ceci mais je ne suis pas à l'aise avec ça.

resolver(auth, $state, $timeout){
   if(!auth.isLoggedIn()){
        $timeout(function () {

             $state.go('noLoggedInPath');
        }, 0);
   }
}
39
Edgar Martinez

Vous pouvez retourner une promesse de votre fonction resolver qui indiquera si vous souhaitez continuer à naviguer vers l'état ou non. Si vous décidez de naviguer ailleurs, rejetez la promesse et spécifiez le bon état:

resolver($q, $state, $timeout, auth) {
    var deferred = $q.defer();

    // $timeout is an example; it also can be an xhr request or any other async function
    $timeout(function() {
      if (!auth.isLoggedIn()) {
        // user is not logged, do not proceed
        // instead, go to a different page
        $state.go('noLoggedInPath');
        deferred.reject();
      } else {
        // everything is fine, proceed
        deferred.resolve();
      }
    });

    return deferred.promise;
}

Plunkr ici .

UPD: code mis à jour et ajouté plunkr. On dirait que cela ne fonctionne que si vous le mettez dans une fonction de délai d'attente.

37
Yauheni Leichanok

La réponse de Yauheni fonctionne, mais pour contourner le problème du délai d'attente étrange, vous pouvez rejeter la promesse et la capturer dans l'événement $ stateChangeError, et y effectuer votre redirection. Ainsi...

state('admin', {
  resolve: {
    auth: function(UserService, $q, permissionService) {
      var deferred = $q.defer();
      return UserService.load().then(function(user){
        if (permissionService.can(user, {goTo: state})) {
          return deferred.resolve({});
        } else {
          return deferred.reject({redirectTo: 'some_other_state'});
        }
      });
    }
  }
});

Et puis ui-router diffuse toujours "stateChangeError", vous pouvez donc faire quelque chose comme ça.

$rootScope.$on('$stateChangeError', function(evt, to, toParams, from, fromParams, error) {
  if (error.redirectTo) {
    $state.go(error.redirectTo);
  } else {
    $state.go('error', {status: error.status})
  }
})
46
bwest87

Je l'utilise

   function Check($state, $q) {
        var deferred = $q.defer();
        if (condition) {
            deferred.resolve();
        }
        else {
            deferred.reject();
        }
        return deferred.promise.catch(function () { $state.go('path'); });
    }
6
Hikmat G.

C'est ce que je fais en réalité et je ne trouve pas de meilleure solution

resolver($q, $timeout, myService) {
    if(!areParameterValuesValid() || !isEverythingLogicallyOk()){
        var deferred = $q.defer();
        $timeout(function() {
            $state.go('somewhere');
            deferred.reject();
        });
        return deferred.promise;
    } else {
        return myService.loadSomething(passingSomeParams);
    }        
}
2
Hovo

Je pense qu'une réponse beaucoup plus claire est de retourner une promesse déjà rejetée comme ceci:

resolver(auth, $state, $q){
   if(!auth.isLoggedIn()){
       $state.go('noLoggedInPath');
       
       // Return rejected promise
       return $q.reject();
   }
   return true;
}

1
Tibo

Utiliser résolus pour cela n'a pas vraiment fonctionné pour moi. J'ai adapté la logique de this post pour exécuter une fonction de redirection sur la propriété data de l 'objet state. Vous pouvez ensuite accéder à l'événement $ stateChangeStart sur $ rootScope à partir du bloc d'exécution du module et utiliser la méthode invoke du service d'injecteur pour modifier l'état en fonction des conditions spécifiées. Fonctionne bien sur tous les modules.

0
Andrew Leonardi

Vous pouvez utiliser les promesses du résolveur avec la configuration redirectTo

   redirectTo: function($transition$) {
      return $transition$.injector().getAsync('isNew').then(function(isNew) {
        return isNew ? 'estate.edit' : 'estate.view';
      });
    },
0
Blowsie