angularjs - 混淆 $locationChangeSuccess 和 $stateChangeStart

标签 angularjs angular-ui-router

我正在尝试使用 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);
    });
  }
});

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

最佳答案

我建议多走“UI-Router 方式”。我们应该使用 $rootScope.$on('$stateChangeStart'事件地点$state.current将适本地提供。这里是 a working example

让我们观察一下简单(但不幼稚)的解决方案,以后可以将其扩展到任何程度。此外,如果您喜欢这种方法,这里有更全面的实现:angular ui-router login authentication

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

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

因此,我们使用异步(此处为 $timeout)来加载 user 对象形成服务器。在我们的示例中,它将有一个属性 {isAuthenticated: false } , 这将用于检查是否已通过身份验证。

还有同步方式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 = ...)。接下来我们将给任何公共(public)方法绿色。这是通过 data {} 完成的。状态对象定义的属性(见 Attach Custom Data to State Objects )

就是这样。如果在下面的代码段中定义了状态,我们可以体验到:
  • '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',
      })
    

  • 检查所有 here

    其他一些资源:
  • angular ui-router login authentication
  • Angular UI Router: nested states for home to differentiate logged in and logged out
  • 其他 state data and authentication
  • 关于angularjs - 混淆 $locationChangeSuccess 和 $stateChangeStart,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25872219/

    相关文章:

    javascript - AngularJS Provider 依赖注入(inject) - 在 provider 中使用 $log

    javascript - Angular自定义$update函数 "is not a function"

    html - 在 select 标签中使用 ngRepeat 两次

    javascript - 根据ng-repeat中的条件动态选择angularjs过滤器

    javascript - 获取 [$injector :unpr] error using Angular. js

    javascript - 如何停止 ui-sref 编码 url 参数

    angularjs - Angular ui-router 1.0.0rc 过渡在重定向上被取代

    angularjs - 在多 View 路由器中解析 $http GET 请求(使用 ui.router)

    angularjs - Atom-shell + AngularJS - 如何打开文件保存对话框?

    javascript - ionic ui-router 解析的结果没有显示在页面中