如何在加载模块控制器之前从远程服务器将一些数据加载到$ rootScope中?

时间:2013-07-03 21:24:46

标签: angularjs

我的模块有一个依赖于$rootScope.foo的控制器,该控制器由$http服务填充。 我的问题是如何确保在加载控制器之前填充$rootScope.foo

我尝试在模块的$rootScope.foo方法中加载run()

myModule.run(function($rootScope, $http, $location) {
  $http.get("http://mydomain/load_user/").
    success(function(respData) {
      $rootScope.foo = respData.foo;
    });
});

但它不起作用,因为控制器在success()内的代码之前加载。

1 个答案:

答案 0 :(得分:9)

使用promises实现$http服务。

您在success处理程序中编写的代码将在解析承诺时运行。由于承诺的异步性质,不知道何时发生这种情况。它可以是1秒后或10秒后。

与此同时,您的其他代码会继续运行,并且您的控制器可能会在承诺解决之前加载。

解决这个问题的最好方法是用“异步”术语思考,而不是强迫某种同步行为。

以下是一些有效选项:

  1. 您可以将代码移动到控制器并将逻辑移动到成功处理程序,如下所示:

    myModule.controller('SomeCtrl', function($rootScope, $http, $location) {
      $http.get("http://mydomain/load_user/").
        success(function(respData) {
          // Perform any logic you need here and use respData.foo;
        });
    });
    
  2. 另一种方法是使用事件通知您的控制器何时解析了承诺(并且数据已从服务器加载),如下所示:

    myModule.run(function($rootScope, $http, $location) {
      $http.get("http://mydomain/load_user/").
        success(function(respData) {
          $rootScope.foo = respData.foo;
    
          // Broadcast event that foo was updated
          $rootScope.$broadcast('fooWasUpdated'); 
        });
    });
    

    然后在您的控制器中,您可以为事件添加一个监听器:

    myModule.controller('SomeCtrl', function($scope, $rootScope) {
    
      $scope.$on('fooWasUpdated', function(event){
        // Perform your logic with $rootScope.foo
      });
    
    });
    
  3. 第三种方法是根本不使用$rootScope,而是使用事件来通知听众并使用如下事件传递数据:

    myModule.run(function($rootScope, $http, $location) {
      $http.get("http://mydomain/load_user/").
        success(function(respData) {
          // Broadcast event that foo was updated
          // You can add data as extra arguments
          $rootScope.$broadcast('fooWasUpdated', respData.foo); 
        });
    });
    

    然后在您的控制器中,您可以为事件添加一个监听器:

    myModule.controller('SomeCtrl', function($scope, $rootScope) {
    
      $scope.$on('fooWasUpdated', function(event, foo){
        // Perform your logic with foo instead of $rootScope.foo
      });
    
    });
    

    您可以在AngularJS documentation for scopes中找到有关$broadcast$on的详细信息。

  4. 使用事件的一些好处是:

    • 您的应用程序中可以有多个侦听器来侦听同一事件
    • 您不必担心在AngularJS中处于正确的范围
    • 您不一定要将数据存储在范围内以便在其他地方使用

    希望有所帮助!