AngularJS 与父子指令竞价的适当事件

AngularJS proper events biding with parent and child directives

我正在尝试实现弹出窗口 window 和显示它的按钮。 我是通过指令来做到这一点的:

<div class="wrapper" wrapper>
  <div class="popup" ng-class="{'popup__active':isActive}">
    Popup message
  </div>
  <button btn>Click me</button>
</div>

当弹出窗口可见时,我需要能够通过单击弹出窗口以外的任意位置来关闭它。

var app = angular.module('plunker', []);

app.controller('MainCtrl', function($scope) {

});

app.directive('wrapper', function($rootScope, $timeout) {
  return {
    link: function($scope, $element) {
      $rootScope.$on('btnclick', function() {
        $scope.isActive = true;
        $scope.$digest();
        $element.bind('click', function() {
          $scope.isActive = false;
          $element.unbind('click');
          $scope.$digest();
        });

      });
    },
  }
});

app.directive('btn', function($rootScope) {
  return {
    link: function($scope, $element) {
      $element.bind('click', function() {
        $rootScope.$broadcast('btnclick');
      });
    },
  }
});

这段代码有问题。 当我单击按钮时,它会显示弹出窗口并立即将其隐藏,因为 'click' 事件在 wrapper link 函数内触发。 但是只有在显示弹出窗口并且我点击它之外的任何地方后才应该触发该点击事件。

请参阅插件:http://plnkr.co/edit/wRbbB7rdgLSaQDZQQEc1

注意:遗憾的是,由于复杂的 CSS 依赖关系,无法在实际项目中更改布局。所以我正在寻找如何使用 angular.

正确绑定元素

根据您当前的结构,您的父元素和子元素都有 click 事件。当您单击任何内部元素时,它会调用该元素的 click 事件,然后它会冒泡该事件,因为父元素具有相同的事件。为防止这种行为,您必须使用 event.stopPropagation() 这将防止在单击事件时冒泡(将事件发送到其父元素)。

指令

app.directive('btn', function($rootScope) {
  return {
    link: function($scope, $element) {
      $element.bind('click', function(e) {
        e.stopPropagation(); //stop bubbling up of event
        $rootScope.$broadcast('btnclick');
      });
    },
  }
});

Demo Plunkr