在Angular中,如何确保在广播消息时加载$ broadcast侦听器

时间:2014-05-23 07:02:11

标签: angularjs angularjs-scope broadcast angularjs-controller

我的Angular应用程序中有两个控制器。当某个数据更新为一个时,它会发出$ broadcast事件,如下所示:

        $scope.updateTableInfo = function (table) {
           $rootScope.$broadcast ("updateTableInfo", table);
        }

在另一个控制器中,有一个监听器,用于监听此更新:

       $rootScope.$on ("updateTableInfo", function (event, table) {
              // do stuff here
       });

不幸的是,似乎如果在第一个控制器中定义了updateTableInfo()之后立即调用它,则第二个控制器还没有准备好收听它,并且错过了更新。如何确保控制器始终可以相互通信?

2 个答案:

答案 0 :(得分:5)

通过在控制器之间共享服务,您可以避免使用$rootScope并为您的计时问题实施简单的解决方案。

您需要创建一个非常简单的服务来保存您想要在控制器之间共享的任何数据/方法:

.factory('SomeService', function(){
  var stuff = {
    thingsToDo: []
  };
  // Other data and methods useful for sharing across controllers here
  return stuff;
});

将服务注入两个控制器:

.controller('FirstController', function($scope, SomeService) { ... });
.controller('SecondController', function($scope, SomeService) { ... });

在一个控制器中创建一个方法来更改服务的状态:

$scope.addTask = function(){
   SomeService.thingsToDo.push({task: 'updateTableInfo'});  
};

在另一个控制器中设置$watch,该控制器将在控制器加载后运行,然后继续监视服务中的更改:

$scope.$watch(function(){ return SomeService.thingsToDo }, function(val){
  angular.forEach(val, function(todo) {
     console.log("Yawn, I guess it's time to:", todo.task);
  });
  // Need to clear in $timeout to avoid infinite digest error
  $timeout(function(){SomeService.thingsToDo = []});
}, true);

Demo

答案 1 :(得分:1)

不要立即调用updateTableInfo函数,而是使用$timeout

调用它
$scope.updateTableInfo = function (table) {
   $rootScope.$broadcast ("updateTableInfo", table);
};
$timeout(function(){
   $scope.updateTableInfo(someArgumentForTable);
},1);