如何只从内部指令中听一次$ document

时间:2014-01-14 12:18:44

标签: angularjs angularjs-directive

我有一个角度指令,需要在click上监听$document个事件 我们称之为 clickDirective

点击监听器已添加到其link功能中 问题是,如果文档中有多个clickDirective,每个都会在click上添加一个新的$document侦听器,从而导致文档点击处理程序功能针对页面上的每个clickDirective触发一次。我只希望它开一次。

但是,回调函数应限定在link函数内,以便它可以访问scopeelementattrs

我尝试将其添加到compile函数中,而点击处理程序仅触发一次,其回调处理程序无法访问link函数内的好东西。

如何实现?

1 个答案:

答案 0 :(得分:2)

在评论中,您说要收听$ document上的文档并使用它来关闭弹出框架泡泡。所以我认为从指令中听取事件可能是正确的。

您可以使用one代替on仅为一个事件绑定事件(在第一次点击后它将解除绑定)。所以像这样:

module.directive('bubble', function ($document) {
  return {
    link: function (scope, element, attrs) {
      element.on('click', function () {
        scope.$apply(function(){
          // Show the bubble here
          $document.one('click', function () {
            scope.$apply(function(){
              // Hide the bubble here
            });
          });
        });
      });
    }
  };
});

如果你真的想在$ document上只听一次你会使用一个服务,那么你将无法访问范围,元素和attrs(因为你期望它们是哪个元素?)。您可以创建一个侦听一次的服务,然后跟踪要关闭的气泡,如下所示:

module.factory('bubbleCloser', function ($document, $rootScope) { 
  var toClose = [];
  $document.on('click', function () {
    $rootScope.$apply(function () {
      toClose.forEach(function (element) {
        element.hide();
      });
      toClose = [];
    });
  });
  return {
    addBubbleElement: function (element) {
      toClose.push(element);
    }
  };
});

这符合您原来的要求,只听一次点击,但更复杂,并没有真正带来任何好处(但如果您没有展示更多内容,可能会有用)。