angularjs - 如何将 StateChangeStart 事件推迟到 ui-router 解析执行之后

标签 angularjs angular-ui-router

我有一个 angular 应用程序,它使用授权逻辑和 ui-router 来禁止未经授权的用户访问某些状态/ View 。我遵循监听 stateChange 事件的标准方法,该事件触发我的授权逻辑。这一切都很好,直到可怕的页面重新加载。

我将 session 数据(包括授权状态)存储在本地存储中,以便在页面重新加载时我可以使用 ui-router 中的父状态在尝试更改 View 之前首先从本地存储解析/获取授权状态。这是我的app的配置父状态对象:

$stateProvider.
state('app', {
  url: '/app',
  abstract: true,
  controller: 'appCtrl',
  data: {
    authorizedRoles: [USER_ROLES.all]
  },
  templateUrl: 'partials/app.html',
  resolve: {

    //Try to restore from the previous session before loading any of the app child states
    RestoredSession: ['SessionService',
             function(SessionService){
                return SessionService.restoreSession();
              }]
  }
})

...various app. child states

这是我的 onStateChange 监听器:
//listen for a ui.router $stateChangeStart event and test the new path to see if the currentUser
//is authorized to view that page

.run(         ['$rootScope', 'AUTH_EVENTS', 'SessionService', 
  function ($rootScope,   AUTH_EVENTS,   SessionService) {

  $rootScope.$on('$stateChangeStart', function (event, next) {
    var authorizedRoles = next.data.authorizedRoles;
    //If the requested page allows guest access, then continue to stateChange
    if (authorizedRoles.indexOf('guest') !== -1 || authorizedRoles.indexOf('*') !== -1) return;

    //If the requested page requires authorization, check login and auth privileges
    if (!SessionService.isAuthorized(authorizedRoles)) {

      event.preventDefault();

      if (SessionService.existingSession()) {

        // user is not allowed
        $rootScope.$broadcast(AUTH_EVENTS.notAuthorized);
        console.log("User attempted to access page for which he is not authorized");

      } else {

        // user is not logged in
        $rootScope.$broadcast(AUTH_EVENTS.notLoggedIn);
        console.log("User attempted to access page when he is not logged in");

      }
    }
  });

}]);

我的问题是 stateChangeStart事件在 app resolve 之前触发这样监听器停止状态更改(通过 event.preventDefault ),然后我的解析加载存储的 session 数据,这通常确定用户一直被授权。如果我可以要求在事件触发之前执行解析,那么我会很高兴。

有什么想法吗???

顺便说一句,这是一个类似的问题,但没有得到答复:Defer Angular UI Router $stateChangeStart until server authorization response receieved

最佳答案

原来我需要做的就是将配置数据的加载移动到 .run()阻止而不是尝试在 parent app 中执行此操作州的resolve .

//listen for a ui.router $stateChangeStart event and test the new path to see if the currentUser
//is authorized to view that page
.run(         ['$rootScope', 'AUTH_EVENTS','SessionService', 'localStorageService',
  function ($rootScope,   AUTH_EVENTS,  SessionService,   localStorageService) 
  {
  $rootScope.$on('$stateChangeStart', function (event, next) {

    //function to check to see if the currentUser has one of the required roles to authorize the next state.
    var checkAuthorization = function(authorizedRoles){

         //If the requested page allows guest access, then continue to stateChange
         if (authorizedRoles.indexOf('guest') !== -1 || authorizedRoles.indexOf('*') !== -1) return;
         //If the requested page requires authorization, check login and auth privileges
         if (!SessionService.isAuthorized(authorizedRoles)) {
           event.preventDefault();
           if (SessionService.existingSession()) {
             // user is not allowed
             $rootScope.$broadcast(AUTH_EVENTS.notAuthorized);
             console.log("User attempted to access page for which he is not authorized");
           } else {
             // user is not logged in
             $rootScope.$broadcast(AUTH_EVENTS.notLoggedIn);
             console.log("User attempted to access page when he is not logged in");
           }
         }
       };

    //Before calling checkAuthorization(), test to see if the state change was triggered by a reload
    //If so, load config data before triggering the `checkAuthorization()` function.
    if (SessionService.freshLoad === true  || typeof SessionService.freshLoad === 'undefined'){
      SessionService.freshLoad = false;
      var storedUser = localStorageService.get('currentUser');

      //If we have a stored user but no existing session, then we know that we have stored
      //user data to reload before the checkAuthorization() function.
      if (typeof storedUser !== "undefined" && storedUser !== null && !SessionService.existingSession()) {
        SessionService.restoreSession();
      }
    }

  checkAuthorization(next.data.authorizedRoles);

  });

}]);

关于angularjs - 如何将 StateChangeStart 事件推迟到 ui-router 解析执行之后,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25799713/

相关文章:

css - 更改事件 View 链接的颜色 UI-Router

html - 无法对齐 html 文件中的两个元素

javascript - Angular ng-option 按键排序

javascript - 为什么我的 $sce.trustAsHtml 内容呈现为纯文本?

javascript - 如何定义CSS以获得简单的选项卡式菜单

javascript - Ui-Router 与父级的深层嵌套状态

java - 如何从 angularjs 调用 Java Controller 类

javascript - 我可以在 ncyBreadcrumb 中有一个动态的 parent 吗?

asp.net-mvc - .NET MVC 和 Angular 与 ui-router

angularjs - "base href"使用 ui-router 在路由 url 中添加目录路径