取消嵌套的ng点击调用之间的事件传播的最好方法是什么?

这是一个例子。 比方说,我想有一个像许多网站的图像覆盖。 所以,当你点击一个缩略图时,整个窗口上会出现一个黑色的叠加层,而图像的一个更大的版本则以它为中心。 点击黑色覆盖层就会解散它。 点击图像将调用一个显示下一个图像的函数。

html:

<div ng-controller="OverlayCtrl" class="overlay" ng-click="hideOverlay()"> <img src="http://some_src" ng-click="nextImage()"/> </div> 

javascript:

 function OverlayCtrl($scope) { $scope.hideOverlay = function() { // Some code to hdie the overlay } $scope.nextImage = function() { // Some code to find and display the next image } } 

问题是,在这个设置下,如果你点击图片, nextImage()hideOverlay()被调用。 但是我想要的只是nextImage()被调用。

我知道你可以在nextImage()函数中捕获和取消事件,如下所示:

 if (window.event) { window.event.stopPropagation(); } 

…但是我想知道是否有一个更好的AngularJS方法,不需要我用这个代码片段在叠加层中的元素前加上所有的函数。

@JosephSilber说了什么,或者将$ event对象传递给ng-clickcallback,并停止它内部的传播:

 <div ng-controller="OverlayCtrl" class="overlay" ng-click="hideOverlay()"> <img src="http://some_src" ng-click="nextImage($event)"/> </div> 
 $scope.nextImage = function($event) { $event.stopPropagation(); // Some code to find and display the next image } 

使用$event.stopPropagation()

 <div ng-controller="OverlayCtrl" class="overlay" ng-click="hideOverlay()"> <img src="http://some_src" ng-click="nextImage(); $event.stopPropagation()" /> </div> 

这是一个演示: http : //plnkr.co/edit/3Pp3NFbGxy30srl8OBmQ?p=preview

我喜欢使用这个指令的想法:

 .directive('stopEvent', function () { return { restrict: 'A', link: function (scope, element, attr) { element.bind('click', function (e) { e.stopPropagation(); }); } }; }); 

然后使用下面的指令:

 <div ng-controller="OverlayCtrl" class="overlay" ng-click="hideOverlay()"> <img src="http://some_src" ng-click="nextImage()" stop-event/> </div> 

如果你想,你可以使这个解决scheme更通用,就像这个答案不同的问题: https : //stackoverflow.com/a/14547223/347216

有时候,这样做可能是最有意义的:

 <widget ng-click="myClickHandler(); $event.stopPropagation()"/> 

我select这样做,因为我不希望myClickHandler()在许多其他地方停止事件传播。

当然,我可以添加一个布尔参数给处理函数,但是stopPropagation()true更有意义。

这适用于我:

 <a href="" ng-click="doSomething($event)">Action</a> this.doSomething = function($event) { $event.stopPropagation(); $event.preventDefault(); }; 

如果你不想把停止传播添加到所有的链接,这也适用。 有点可扩展性。

 $scope.hideOverlay( $event ){ // only hide the overlay if we click on the actual div if( $event.target.className.indexOf('overlay') ) // hide overlay logic } 

如果在模板的父元素中插入ng-click =“$ event.stopPropagation”,则stopPropogation将被捕获,因为它会冒泡树,所以您只需为整个模板编写一次。

您可以在ng-click之上注册另一个指令,修改ng-click的默认行为并停止事件传播。 这样你就不必手工添加$event.stopPropagation

 app.directive('ngClick', function() { return { restrict: 'A', compile: function($element, attr) { return function(scope, element, attr) { element.on('click', function(event) { event.stopPropagation(); }); }; } } }); 

IN控制器使用

$ scope.methodName = function(event){event.stopPropagation();}