【问题标题】:How do you load data asynchronously when loading an angular module?加载角度模块时如何异步加载数据?
【发布时间】:2013-07-30 15:07:24
【问题描述】:

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

我一直致力于在 module.run 方法中做一些事情,但我找不到阻止它继续的方法,直到从服务器取回数据。我发现了这个,但它遇到了同样的问题:AngularJS : Initialize service with asynchronous data。

我也可以进行手动引导,但我找不到任何如何做到这一点的好例子。如果您能提供任何帮助,我们将不胜感激。

【问题讨论】:

    标签: angularjs asynchronous startup deferred-loading


    【解决方案1】:

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

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

    【讨论】:

      【解决方案2】:

      就像已经提到的其他答案一样,您应该注意应用的安全性。

      可能的解决方案是:

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

      在您的 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。

      【讨论】:

      • 有没有办法在等待 get 返回时暂停应用加载?
      • 当然。例如,您可以使用在请求的成功块中设置为“true”的简单布尔值。然后,您可以在运行块中收听 $routeChangeStart。如果布尔值为 false,您可以将用户重定向到加载页面。
      猜你喜欢
      • 2012-12-04
      • 1970-01-01
      • 1970-01-01
      • 2020-10-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-10-26
      • 1970-01-01
      相关资源
      最近更新 更多