以可变状态加载角度为ui-router的路由器

问题描述:

根据用户的权限,我有两种默认状态之一(我们称之为foobar)在登录后显示。我有一个在$stateChangeStart上运行的函数,它使用用户的权限将它们重定向到正确的屏幕。以可变状态加载角度为ui-router的路由器

foo权限 - >mybrokenapp.com/foo/dashboard
bar权限 - >mybrokenapp.com/bar/dashboard

这工作完全在用户通过登录页面进入。但是,如果用户登录(设置了cookie)并仅访问根URL(mybrokenapp.com),则重定向不再起作用。

我已调试到99%确定该错误是由于运行$stateChangeStart时未设置currentRole造成的。

路由代码:

$stateProvider 
      .state('app', { 
       templateUrl: '/path/app.html', 
       url : '', 
       resolve: { 
        authenticated: ['authService',  function(authService){ 
         return authService.authenticationStatus(true); 
        }] 
       } 

      }) 

      .state('app.foo', { 
       abstract: true, 
       template: '<ui-view/>', 
       url: "/foo" 
      }) 

      .state('app.foo.dashboard', { 
       templateUrl: '/path/dashboard.foo.html', 
       url: "/dashboard", 
       controller: 'DashFoo', 
       controllerAs: 'dashFoo' 

      }) 
      .state('app.bar', { 
       abstract: true, 
       template: '<ui-view/>', 
       url: "/bar" 
      }) 

      .state('app.bar.dashboard', { 
       templateUrl: '/path/dashboard.bar.html', 
       url: "/dashboard", 
       controller: 'DashBar', 
       controllerAs: 'dashBar' 

      }) 

      .state('login', { 
       templateUrl: '/path/login.html', 
       url: "/login", 
       controller: 'LoginCtrl' 
      }) 

一个重定向到基于权限正确的URL的功能:

.run(function($rootScope, $state, authService, userService){ 
     authService.initialize('/api', true); 

     $rootScope.$on('$stateChangeStart', function (event, toState) { 
      if (toState.name === 'app') { 
       if (userService.getUserRoles().currentRole == 'foo') { 
        event.preventDefault(); 
        $state.go('app.foo.dashboard'); 
       } 
       if (userService.getUserRoles().currentRole == 'bar') { 
        event.preventDefault(); 
        $state.go('app.bar.dashboard'); 
       } 
      } 
     }); 
    }); 

就如何解决这个问题,或者替代路线的设计,还是任何想法提供相同的功能,将不胜感激。

我自己设法解决了这个问题。在ui-router github pages中发现了这个有趣的讨论。

初始化状态的定义与决心:

问题要解决{}可以访问由UI路由器内部使用的实际解决的对象,并允许$ stateChangeStart内

添加做出决议

的代码:

.run(function($rootScope, $state, authService, userService, $timeout){ 
    authService.initialize('/api', true); 

    $rootScope.$on('$stateChangeStart', function (event, toState) { 
     if (toState.name === 'app') { 
      toState.resolve.x = function() { 
        $timeout(function(){ userService.setUserRoles(authService.user); }, 30).then(function(){ 

         if (userService.getUserRoles().currentRole == 'foo') { 
          event.preventDefault(); 
          $state.go('app.foo.dashboard'); 
         } 
         if (userService.getUserRoles().currentRole == 'bar') { 
          event.preventDefault(); 
          $state.go('app.bar.dashboard'); 
         } 
        }); 
       }; 
     } 
    }); 
}); 

30 milisecond超时需要,得到authService时间来加载。虽然这并不理想,但它的工作原理。

对上述代码的任何改进都值得欢迎。

请检查我在这个问题中给出的答案。它提供了替代和可以更好的设计 Angular Authentication and Access control

在答案u可以根据您的需要轻松扩展boolean authenticate参数。并且仅在$ stateChange事件中调用认证服务。