Angularjs 如何在模块';s控制器是否已加载?

Angularjs 如何在模块';s控制器是否已加载?,angularjs,Angularjs,我的模块有一个依赖于$rootScope.foo的控制器,该控制器通过使用$http服务填充我的问题是如何确保在加载控制器之前填充$rootScope.foo。 我尝试在模块的run()方法中加载$rootScope.foo: myModule.run(function($rootScope, $http, $location) { $http.get("http://mydomain/load_user/"). success(function(respData) {

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

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

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

但是它不起作用,因为在
success()

中的代码被加载之前,
$http
服务是使用承诺实现的

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

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

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

以下是一些有效的选项:

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

    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;
        });
    });
    
    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.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($rootScope, $http, $location) {
      $http.get("http://mydomain/load_user/").
        success(function(respData) {
          // Perform any logic you need here and use respData.foo;
        });
    });
    
    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.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){
        // Perform your logic with $rootScope.foo
      });
    
    });
    
    myModule.controller('SomeCtrl', function($scope, $rootScope) {
    
      $scope.$on('fooWasUpdated', function(event, foo){
        // Perform your logic with foo instead of $rootScope.foo
      });
    
    });
    
  • 第三种方法是根本不使用
    $rootScope
    ,而是使用事件通知侦听器,并通过事件传递数据,如下所示:

    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;
        });
    });
    
    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.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){
        // Perform your logic with $rootScope.foo
      });
    
    });
    
    myModule.controller('SomeCtrl', function($scope, $rootScope) {
    
      $scope.$on('fooWasUpdated', function(event, foo){
        // Perform your logic with foo instead of $rootScope.foo
      });
    
    });
    
    您可以在中找到有关
    $broadcast
    $on
    的详细信息

  • 使用事件的几个好处是:

    • 应用程序中可以有多个侦听器侦听同一事件
    • 在AngularJS中,您不必担心是否在正确的范围内
    • 您不必将数据存储在某个作用域中,以使其在其他地方可用
    希望有帮助