使用ui-router以角度加载变量状态

时间:2016-01-21 07:16:19

标签: javascript angularjs angular-ui-router

根据用户的权限,我在登录后会显示两种默认状态之一(让我们称之为foobar)。我有一个在$stateChangeStart上运行的功能,它使用用户的权限将它们重定向到正确的屏幕。

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

当用户通过登录页面进入时,这非常有效。但是,如果用户已登录(已设置Cookie)并且只访问根网址(mybrokenapp.com),则重定向不再有效。

我调试了这一点,以至于99%确定错误是由currentRole运行时$stateChangeStart未设置引起的。

路由代码:

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

根据权限重定向到正确网址的功能:

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

有关如何解决此问题的任何想法,或仍然提供相同功能的替代路线设计,将不胜感激。

2 个答案:

答案 0 :(得分:0)

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

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

答案 1 :(得分:0)

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

问题解决了:

  

使用resolve初始化状态定义:{}可以访问ui-router内部使用的实际解析对象,并允许在$ 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毫秒的超时才能加载authService时间。虽然这绝不是理想的,但它确实有效。

对上述代码的任何改进都非常受欢迎。