如何将指令中的事件从AngularJS中的其他控制器广播

时间:2014-11-15 11:33:23

标签: angularjs angularjs-directive angularjs-scope

我需要以某种方式从页面的一部分(滚动,单击)发出事件,该事件由一个指令提供给页面的其他部分,由其他控制器提供,以便可以相应地更新。用例 - 例如带有注释的Word文档,该注释与视口中的页面一起移动。 因此,在我的设计中,我有指示链接方法,我需要将其中的事件广播到我的应用程序中的其他控制器。我的链接功能里面有什么:

 element.bind('click', function (e) { 
    var eventObj = element.scrollTop();
    scope.$broadcast('app.scrollOnDocument', eventObj);
 });

这个事件我不能直接在其他控制器中看到 - 所以在其他控制器中这样的代码不起作用:

$scope.$on('app.scrollOnDocument', function (e, params) {
   console.log(e, params);
});

所以我要做的是拦截同一指令控制器中的那些事件,并将它们广播到更高的范围,如:

$scope.$on('app.scrollOnDocument', function(event, params){
     //go further only if some_condition
      if( some_condition ){
         $rootScope.$broadcast('app.scrollOnDocumentOuter', params);
      }
});

我不确定这是否是正确的做法。也许我错过了一些指令属性或设置使其成为可能?

2 个答案:

答案 0 :(得分:6)

非标准服务可以传递给指令,如

.directive('notify', ['$rootScope', '$interval', function(rootScope, interval){

    return {
      restrict : 'E',
      link : function(){
          interval(function(){
            rootScope.$broadcast('custom.event', new Date());
          }, 1500);

        }
      };
}]);

以下示例每1500毫秒广播一次事件。

如果无法避免使用rootScope进行通信,则应始终尝试取消注册侦听器。

angular.module('app', [])
  .controller('indexCtrl', ['$rootScope', '$scope',
    function(rootScope, scope) {
      scope.title = 'hello';
      scope.captured = [];

      var unregister = rootScope.$on('custom.event', function(evt, data) {
        scope.captured.push(data);
      });

      scope.$on('$destroy', function() {
        unregister();
      });

    }
  ])
  .directive('notify', ['$rootScope', '$interval',
    function(rootScope, interval) {

      return {
        restrict: 'E',
        link: function() {
          interval(function() {
            rootScope.$broadcast('custom.event', new Date());
          }, 1500);

        }
      };
    }
  ]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>

<div ng-app="app" ng-controller="indexCtrl">
  <h1>{{title}}</h1>
  <notify></notify>
  <ul>
    <li ng-repeat="event in captured">{{event|date:'medium'}}</li>
  </ul>
</div>

答案 1 :(得分:0)

对于AngularJS中的广播,您始终必须使用$rootScope。您始终在$scope而不是$rootScope上聆听。