拦截器或$ stateChangeStart事件使用$ location

时间:2016-07-26 15:03:28

标签: angularjs authentication routing angular-ui-router

如果用户尚未登录,我正在编写拦截器以重定向到登录页面。我使用$ location更改浏览器地址。

然而,代码有效,“有时”如果键入一个用于记录用户的URL(例如:http://localhost:4662/#/index/companies),浏览器会加载“公司”模板并将URL地址更改为登录页面:( http://localhost:4662/#/)。所以我必须按Enter才能真正重定向到登录页面。它有时会发生(有时意味着我可以多次这样做,我得到预期的行为,但突然间它没有达到预期的效果)

这是我的代码:

$httpProvider.interceptors.push(function ($q, $rootScope, $location, $injector) {

        return {
            request: function (config) {

                //the same config / modified config / a new config needs to be returned.
                var applicationService = $injector.get('applicationService');

                var loggedIn = applicationService.isLoggedIn();
                if (!loggedIn) {
                    $location.path('/');
                    //$window.location.href = "#";
                } else if ($location.path() == '/') {
                    $location.path('/index');                       
                     }

                return config;
            },
           requestError: function (rejection) {...... 

我没有使用拦截器,而是按照以下方式尝试实现路由更改侦听器,但我遇到了完全相同的问题:

    app.run(function($rootScope, $state, $location, applicationService){
        $rootScope.$on('$stateChangeStart', function(event, toState, toParams, fromState, fromParams){
            var loggedIn = applicationService.isLoggedIn();
            if (!loggedIn) {
                $location.path('/');                    
            } else if (toState.name == 'home') {
                $location.path('/index');
            }
        });
    });

我做错了什么?我想知道$ location是不是正确的选择。

2 个答案:

答案 0 :(得分:1)

通常在使用ui-router时,可以使用go对象的$state方法以编程方式更改状态:

$state.go(to [, toParams] [, options])
  

转换到新状态的便捷方法。 $ state.go在内部调用$ state.transitionTo但自动将选项设置为{location:true,inherit:true,relative:$ state。$ current,notify:true}。这允许您轻松使用绝对路径或相对路径,并仅指定您想要更新的参数(同时让未指定的参数从当前状态继承。

https://github.com/angular-ui/ui-router/wiki/Quick-Reference#stategoto--toparams--options

答案 1 :(得分:0)

最后找到的解决方案是:

    app.run(function($rootScope, $state, $location, applicationService){
        $rootScope.$on('$stateChangeStart', function(event, toState, toParams, fromState, fromParams){
            var loggedIn = applicationService.isLoggedIn();

            //Go to home butis logged, redirect to main page (connections)
            if (toState.name == 'home' && loggedIn) {
                event.preventDefault();
                $state.go('index');
                return;
            }

            if (toState.name === 'home') {
                // doe she/he try to go to login? - let him/her go
                return;
            }

            if (loggedIn) {
                // is logged in? - can go anyhwere
                return;
            }

            // else, is logged in? No- Go to login
            event.preventDefault();
            $state.go('home');


        });
    });