Change state of angular app from resolve method of state provider

谁都会走 提交于 2020-01-04 04:39:14

问题


I'm using ui-router in my angular application. Currently I've two routes /signin & /user. Initially it shows /signin when the user clicks on the login button, I'm sending a ajax request and getting the user id. I'm storing the user id in localstorage and changing the state to /user.

Now, what I want, if a user is not loggedin, and user changes the addressbar to /user, it'll not change the view, instead it'll change the addressbar url to /signin again.

I'm try to use resolve, but it's not working. My code is:-

module.exports = function($stateProvider, $injector) {
$stateProvider
.state('signin', {
    url: '/signin',
    template: require('../templates/signin.html'),
    controller: 'LoginController'
})
.state('user', {
    url: '/user/:id',
    template: require('../templates/user.html'),
    resolve:{
        checkLogin:  function(){
             var $state = $injector.get('$state');
            console.log("in resolve");
             if (! window.localStorage.getItem('user-id')) {
                 console.log("in if")
                  $state.go('signin');
             }
        }
    },
    controller: 'UserController'
 })

}

Please help me to solve this problem.


回答1:


I don't think it's allowed to change states in the middle of a state transition.

So, the way to address it is to have the checkLogin resolve parameter (I changed it below to userId) to be a function that either returns a value or a promise (in this case, a rejected promise, if you can't get the user-id).

You'd then need to handle this in $rootScope.$on('$stateChangeError') and check the error code.

resolve: {
   userId: function ($q, $window) {
      var userId = $window.localStorage.getItem('user-id');
      if (!userId) {
         return $q.reject("signin")
      }

      return userId;
   }
}

And redirect in the $stateChangeError handler:

$rootScope.$on('$stateChangeError', function (event, toState, toParams, fromState, fromParams, error) {
     if (error === "signin") {
        $state.go("signin");
     }
});



回答2:


If someone has this problem, you can solve it, using timeout service. It will put state switching call at the end of queue.

Also, you should use promises. Rejecting it will prevent initialization of that state:

resolve:{
    checkLogin: function(){

         var deferred = $q.defer();

         var $state = $injector.get('$state');
         if (!window.localStorage.getItem('user-id')) {
             $timeout(function(){$state.go('signin');});
             deferred.reject();
         } else {
             deferred.resolve();
         }

         return deferred.promise;
    }
},


来源:https://stackoverflow.com/questions/27569317/change-state-of-angular-app-from-resolve-method-of-state-provider

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!