混乱$ locationChangeSuccess和$ stateChangeStart [英] Confusing $locationChangeSuccess and $stateChangeStart

查看:2131
本文介绍了混乱$ locationChangeSuccess和$ stateChangeStart的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图做AngularUI路由器一些认证。 $ urlRouter.sync()的样子正是我需要的。然而,当我拦截 $ locationChangeSuccess 这是唯一可用的。但是,当我做到这一点, $ state.current.name 是空的,而我希望它是当前的状态。

I am trying to do some authentication with AngularUI Router. $urlRouter.sync() looks like exactly what I need. However, that's only available when I intercept $locationChangeSuccess. But when I do that, $state.current.name is empty, whereas I want it to be the current state.

下面是我的code迄今:

Here's my code so far:

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

任何指针,以什么我做错了?

Any pointers as to what I'm doing wrong?

推荐答案

我建议去更多的 UI-路由器办法。我们应该用 $ rootScope。在$('$ stateChangeStart事件,其中 $ state.current 将各得其所。这里是

I would suggest to go more "UI-Router way". We should use $rootScope.$on('$stateChangeStart' event where $state.current would be properly provided. Here is a working example

让我们看到简单的(但不幼稚)的解决方案,它可以在以后扩展到任何程度。此外,如果你会喜欢这种方法,这里是更加融为一体prehensive实施:角UI路由器的登录验证

Let's observe simple (but not naive) solution, which could be extended to any degree later. Also if you will like this approach, here is much more comprehensive implementation: angular ui-router login authentication

首先,让我们这样定义我们的用户服务:

Firstly, let's have our user service defined like this:

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

所以,我们使用异步的(这里 $超时的加载 用户 对象形成一个服务器。在我们的例子,将有一个属性 {isAuthenticated:假} ,这将被用来检查是否被认证

So, we use async (here $timeout) to load user object form a server. In our example it will have a property {isAuthenticated: false }, which will be used to check if is authenticated.

也有同步的方法 isAuthenticated()其中,直到用户加载并允许 - 总是返回

There is also sync method isAuthenticated() which, until user is loaded and allowed - always returns false.

而这将是我们的'$ stateChangeStart事件监听器:

And that would be our listener of the '$stateChangeStart' event:

.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 = ... 的。下一步,我们将给予绿色的公共方法。这与数据进行{} 状态对象定义的属性(见的附加自定义数据来状态对象

What we are checking first, is if user is already loaded and authenticated (var isAuthenticated = ...). Next we will give green to any public method. This is done with the data {} property of the state object definition (see Attach Custom Data to State Objects)

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

And that's it. In case of states defined like in a below snippet we can experience:


  • 公共'家'允许任何人

  • 私人私人将重定向到登录,如果 isAuthenticated = ==虚假

  • 登录在这个例子中提供了快捷的方式如何切换isAuthenticated开/关

  • the 'public', 'home' are allowed to anybody
  • the 'private', 'private' will redirect to login if isAuthenticated === false
  • the 'login' in this example provides quick way how to switch isAuthenticated on/off

// 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',
  })


检查所有这里

其他的一些资源:

这篇关于混乱$ locationChangeSuccess和$ stateChangeStart的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆