How to redirect in a ui-router resolver?

前端 未结 7 706
我寻月下人不归
我寻月下人不归 2021-02-03 17:58

I am trying to redirect inside a ui-router resolve and wanted to know if there is a way to reroute in a router resolver. Currently this does not work as one would think.

相关标签:
7条回答
  • 2021-02-03 18:27

    I think a much cleaner answer is to return an already rejected promise like so:

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

    0 讨论(0)
  • 2021-02-03 18:32

    Yauheni's answer does work, but to get around the weird timeout thing, you can reject the promise, and catch that in the $stateChangeError event, and do your redirect there. Like so...

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

    And then ui-router always broadcasts "stateChangeError", so you can do something like this..

    $rootScope.$on('$stateChangeError', function(evt, to, toParams, from, fromParams, error) {
      if (error.redirectTo) {
        $state.go(error.redirectTo);
      } else {
        $state.go('error', {status: error.status})
      }
    })
    
    0 讨论(0)
  • 2021-02-03 18:33

    This is what I actually do, and I can't find a better 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);
        }        
    }
    
    0 讨论(0)
  • 2021-02-03 18:49

    I use this

       function Check($state, $q) {
            var deferred = $q.defer();
            if (condition) {
                deferred.resolve();
            }
            else {
                deferred.reject();
            }
            return deferred.promise.catch(function () { $state.go('path'); });
        }
    
    0 讨论(0)
  • 2021-02-03 18:49

    You can use resolver promises from with the redirectTo configuration

       redirectTo: function($transition$) {
          return $transition$.injector().getAsync('isNew').then(function(isNew) {
            return isNew ? 'estate.edit' : 'estate.view';
          });
        },
    
    0 讨论(0)
  • 2021-02-03 18:50

    Using resolves for this didn't quite work out for me. I adapted the logic from this post to execute a redirect function on the data property of the state object. You can then tap into the $stateChangeStart event on $rootScope from the run block of the module and use the injector service's invoke method to the change the state based on the conditions you specify. Works nicely across modules as well.

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