有没有办法防止我的angularjs应用程序启动时加载初始状态?

时间:2014-07-03 14:50:28

标签: javascript django angularjs angular-ui-router

背景

我的应用程序需要向服务器发出请求,以便在加载第一个状态之前验证用户是否具有经过身份验证的会话。根据网址的不同,用户可能需要重定向到登录页面。

即如果初始网址为myapp.com/#/profile并且用户没有预先存在的经过身份验证的会话,则他们会被重定向到myapp.com/#/login


问题

我有处理这种情况的逻辑,但在向服务器发出会话数据请求之后,在服务器完成之前,会立即触发初始状态更改,并在服务器响应之前加载并显示页面


可能的解决方案

1)我使用django作为我的后端,因此可以从应用程序中删除初始服务器请求,并将数据直接传递到django模板中的应用程序。通过

    主控制器的
  • ng-init - 虽然我读过这是一个 坏主意,因为它不是它的预期用途

  • 或者在django模板中的脚本标签中 - 我不喜欢 做,因为我宁愿将我的所有应用程序逻辑分别保存在js文件中

2)监听初始$ stateChangeStart,取消它然后在服务器请求完成后调用$ state.reload()


问题

在我看来,在初始状态发生变化之前满足某些标准是一个相当普遍的要求,所以我想知道我是否错过了文档中的某些内容,而且已经有了一种内置的方式来处理这种情况?

或者有没有办法停用$ urlRouterProvider / $ stateProvider以防止发生初始状态更改?

1 个答案:

答案 0 :(得分:5)

假设您的所有身份验证逻辑已经在AuthService之内,那么是否可以执行以下操作?

// 'AuthService' injected earlier
$rootScope.$on('$stateChangeStart', function(event, toState, toParams, fromState, fromParams) {
    if (!AuthService.isAuthenticated()) {
        // prevent navigation. don't go anywhere;
        // navigation will occur inside AuthService
        event.preventDefault();

        AuthService.setNextState(toState.name);
        AuthService.authenticateWithServer();
    }
    // proceed normally if user is already authenticated
});

然后,您的AuthService

app.service('AuthService', function($rootScope, $http, $state) {
    var next;

    this.setNextState = function(nextState) { next = nextState; };

    this.isAuthenticated = function() { ... };

    this.authenticateWithServer = function() {
        $http.post('/authen', { ... }).success(function(user){
            // house-keeping
            $rootScope.user = user;

            // navigate by state name
            $state.go(next);
        }).error(function(error) {
            // navigate to login screen
            $state.go('login');
        });
    };
});

这样,您的状态定义是干净的,并且身份验证逻辑在一个地方被隔离。您还可以确保在获得所需信息之前永远不会进行导航。