【问题标题】:In Angular, how to make sure that $broadcast listener is loaded when a message is broadcast在 Angular 中,如何确保在广播消息时加载 $broadcast 侦听器
【发布时间】:2014-05-23 07:02:11
【问题描述】:

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

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

在另一个控制器中,设置了一个侦听器来侦听此更新:

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

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

【问题讨论】:

  • 你最好使用服务在控制器之间进行交叉通信,尤其是在这里。

标签: angularjs angularjs-scope broadcast angularjs-controller


【解决方案1】:

通过在控制器之间共享服务,您可以避免使用$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

【讨论】:

  • 考虑到我的问题,我认为这是最好的解决方案。不污染根范围,做需要做的事。
【解决方案2】:

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

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

【讨论】:

  • 一个合理的解决方案。我最终只是将表变量放在根范围内,并在另一个控制器中为它设置了一个监视:这似乎始终如一。
  • @allenrabinovich 不要把table变量放在rootScope中,而是创建一个包含table参数的服务,然后观察它。这比poluting rootScope
  • 我的回答中的示例可能有点太可爱了,但它确实说明了带有 $watch 的共享服务。
  • @allenrabinovich 如果您设计了这样的解决方案,您能否在答案中描述/演示它并标记为已接受?
  • 根据我的经验,这并不总是奏效,我不得不将超时时间增加到 100 毫秒以上,这似乎很 hacky。仍在寻找解决方案,但可能会提供另一个共享服务。
猜你喜欢
  • 2015-11-04
  • 1970-01-01
  • 2022-07-08
  • 2016-03-13
  • 1970-01-01
  • 2013-11-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多