加载角度模块时如何异步加载数据?

时间:2013-07-30 15:07:25

标签: angularjs asynchronous startup deferred-loading

在我的角度应用程序中,我需要在允许其余应用程序运行之前从服务器读取一些数据。例如,我需要对用户进行身份验证,以便在允许他们访问任何内容之前验证他们的权限。由于我需要在app启动时执行此操作并且我不知道将首先加载哪个控制器,因此我无法使用$ routeProvider.when方法的resolve功能,因为我不知道将首先命中哪个控制器,并且它只在应用程序启动时出现一次。

我一直在使用module.run方法做一些事情,但是我找不到一种方法来阻止它继续,直到从服务器返回数据。我找到了这个,但它遇到了同样的问题:AngularJS : Initialize service with asynchronous data

我也可以进行手动引导,但是我找不到任何有关如何执行此操作的好例子。您可以提供任何帮助。

2 个答案:

答案 0 :(得分:1)

我能想到的最简单的方法就是有一个单独的登录页面。用户通过身份验证后,只允许他访问主应用程序(角度应用程序)。

此外,您需要保护服务资源免受未经授权的请求。这可以防止您的控制器\视图加载未经授权的数据。

答案 1 :(得分:1)

与上面提到的其他答案一样,您应该注意应用的安全性。

可能的解决方案是:

检查用户是否已通过身份验证

在您的API中实施身份验证。您可以使用responseInterceptor检查用户是否已登录:

.config(['$routeProvider','$httpProvider', function($routeProvider,$httpProvider) {

  //setup your routes here...   

  var authChecker = ['$location', '$q', function($location, $q) {
      //redirects the user to /login page if he's not authorized (401)
      function success(response) {
          return response;
      }

      function error(response) {

          if(response.status === 401) {
              $location.path('/login');
              return $q.reject(response);
          }
          else {
              return $q.reject(response);
          }
      }

      return function(promise) {
          return promise.then(success, error);
      }
  }];

  $httpProvider.responseInterceptors.push(authChecker);
}])

有关详细信息,请参阅$http docs

解决方法:运行范围

不解决安全问题,但也有效:

在运行块中获取数据,如下所示:

.run(function($http,$location,$rootScope) {
    $rootScope.$on("$routeChangeStart", function (event, next, current) {
        if($rootScope.gotData) {
             $location.path(next.path);
        } else {
            $location.path('/loading');
        }
    });

    $http.get('path/to/data').success(function() {
        $rootScope.gotData = true;
        $location.path('/home');
    }).error(function() {
        $location.path('/404');
    })
})

请参阅docs了解详情。