小编典典

$ locationChangeSuccess和$ stateChangeStart混淆

angularjs

我正在尝试使用AngularUI路由器进行一些身份验证。$urlRouter.sync()看起来正是我所需要的。但是,仅当我拦截时可用$locationChangeSuccess。但是当我这样做时,它$state.current.name是空的,而我希望它是当前状态。

到目前为止,这是我的代码:

$rootScope.$on('$locationChangeSuccess', function(event, next, nextParams) {
  event.preventDefault();
  if ($state.current.name === 'login') {
    return userService.isAuthenticated().then(function(response) {
      var authenticated;
      authenticated = response.authenticated;
      return alert(authenticated);
    });
  }
});

关于我在做什么错的任何指示?


阅读 221

收藏
2020-07-04

共1个答案

小编典典

我建议走更多的UI- Router路。我们应该使用适当提供的$rootScope.$on('$stateChangeStart'事件$state.current。这是一个有效的例子

让我们观察一下简单的 (但不是幼稚的) 解决方案,它可以在以后扩展到任何程度。

首先,让我们定义用户服务,如下所示:

.factory('userService', function ($timeout, $q) {

    var user = undefined;

    return {
        // async way how to load user from Server API
        getAuthObject: function () {
            var deferred = $q.defer();

            // later we can use this quick way -
            // - once user is already loaded
            if (user) {
                return $q.when(user);
            }

            // server fake call, in action would be $http
            $timeout(function () {
                // server returned UN authenticated user
                user = {isAuthenticated: false };
                // here resolved after 500ms
                deferred.resolve(user)
            }, 500)

            return deferred.promise;
        },

        // sync, quick way how to check IS authenticated...
        isAuthenticated: function () {
            return user !== undefined
                && user.isAuthenticated;
        }
    };    
})

因此,我们使用async _(此处为$timeout)_从user服务器加载对象。在我们的示例中,它将具有属性{isAuthenticated: false },该属性将用于检查是否已通过身份验证。

还有一个sync方法isAuthenticated(),直到加载并允许用户-始终返回false

那将是我们对'$stateChangeStart'事件的听众:

.run(['$rootScope', '$state', 'userService',
 function ($rootScope, $state, userService) {

     $rootScope.$on('$stateChangeStart', function (event, toState,   toParams
                                                        , fromState, fromParams) {    
        // if already authenticated...
        var isAuthenticated = userService.isAuthenticated();
        // any public action is allowed
        var isPublicAction = angular.isObject(toState.data)
                           && toState.data.isPublic === true;

        if (isPublicAction || isAuthenticated) {
          return;
        }

        // stop state change
        event.preventDefault();

        // async load user 
        userService
           .getAuthObject()
           .then(function (user) {

              var isAuthenticated = user.isAuthenticated === true;

              if (isAuthenticated) {
                // let's continue, use is allowed
                $state.go(toState, toParams)
                return;
              }    
              // log on / sign in...
              $state.go("login");
           })
       ...

我们首先要检查的是用户是否已经加载并通过身份验证 var isAuthenticated = ...。接下来,我们将为任何公共方法赋予绿色。这是通过data {}状态对象定义的属性完成的(请参阅将自定义数据附加到状态对象

就是这样。在下面的代码段中定义状态的情况下,我们可以体验到:

  • 'public''home'允许任何人
  • 'private''private'如果出现以下情况,将重定向到登录名isAuthenticated === false
  • 'login'这个例子提供了快捷的方法如何打开/关闭isAuthenticated

    // States
    

    $stateProvider

    // public
    .state(‘home’, {
    url: “/home”,
    templateUrl: ‘tpl.html’,
    data: { isPublic: true },
    })
    .state(‘public’, {
    url: “/public”,
    templateUrl: ‘tpl.html’,
    data: { isPublic: true },
    })
    // private
    .state(‘private’, {
    url: “/private”,
    templateUrl: ‘tpl.html’,
    })
    .state(‘private2’, {
    url: “/private2”,
    templateUrl: ‘tpl.html’,
    })

    // login
    .state(‘login’, {
    url: “/login”,
    templateUrl: ‘tpl.html’,
    data: { isPublic: true },
    controller: ‘loginCtrl’,
    })

检查所有这里

2020-07-04