AngularJS ng-click stopPropagation

我有一个表行上的单击事件,在这一行还有一个单击事件的删除button。 当我点击删除button单击该行上的事件也被激发。

这是我的代码。

<tbody> <tr ng-repeat="user in users" class="repeat-animation" ng-click="showUser(user, $index)"> <td>{{user.firstname}}</td> <td>{{user.lastname}}</td> <td>{{user.email}}</td> <td><button class="btn red btn-sm" ng-click="deleteUser(user.id, $index)">Delete</button></td> </tr> </tbody> 

我怎样才能防止showUser事件被激发,当我点击表格单元格中的删除button?

ngClick指令(以及所有其他事件指令)创build$eventvariables,它在相同的作用域上可用。 这个variables是对JS event对象的引用,可以用来调用stopPropagation()

 <table> <tr ng-repeat="user in users" ng-click="showUser(user)"> <td>{{user.firstname}}</td> <td>{{user.lastname}}</td> <td> <button class="btn" ng-click="deleteUser(user.id, $index); $event.stopPropagation();"> Delete </button> </td> </tr> </table> 

PLUNKER

除了Stewie的回答。 如果您的callback决定传播是否应该停止,我发现将$event对象传递给callback是有用的:

 <div ng-click="parentHandler($event)"> <div ng-click="childHandler($event)"> </div> </div> 

然后在callback本身中,您可以决定是否停止事件的传播:

 $scope.childHandler = function ($event) { if (wanna_stop_it()) { $event.stopPropagation(); } ... }; 

我写了一个指令,可以让你限制点击有效的区域。 它可以用于像这样的特定场景,所以不必处理点击的情况下,你可以说“点击不会出这个元素”。

你会这样使用它:

 <table> <tr ng-repeat="user in users" ng-click="showUser(user)"> <td>{{user.firstname}}</td> <td>{{user.lastname}}</td> <td isolate-click> <button class="btn" ng-click="deleteUser(user.id, $index);"> Delete </button> </td> </tr> </table> 

请记住,这将阻止所有点击最后一个单元格,而不仅仅是button。 如果这不是你想要的,你可能想要包装这样的button:

 <span isolate-click> <button class="btn" ng-click="deleteUser(user.id, $index);"> Delete </button> </span> 

这里是指令的代码:

 angular.module('awesome', []).directive('isolateClick', function() { return { link: function(scope, elem) { elem.on('click', function(e){ e.stopPropagation(); }); } }; }); 

如果你正在使用像我这样的指令,当你需要两个数据绑定的时候,例如在任何模型或集合中更新一个属性之后,

 angular.module('yourApp').directive('setSurveyInEditionMode', setSurveyInEditionMode) function setSurveyInEditionMode() { return { restrict: 'A', link: function(scope, element, $attributes) { element.on('click', function(event){ event.stopPropagation(); // In order to work with stopPropagation and two data way binding // if you don't use scope.$apply in my case the model is not updated in the view when I click on the element that has my directive scope.$apply(function () { scope.mySurvey.inEditionMode = true; console.log('inside the directive') }); }); } } } 

现在,你可以很容易地使用它在任何button,链接,div等,如下所示:

 <button set-survey-in-edition-mode >Edit survey</button> 
 <ul class="col col-double clearfix"> <li class="col__item" ng-repeat="location in searchLocations"> <label> <input type="checkbox" ng-click="onLocationSelectionClicked($event)" checklist-model="selectedAuctions.locations" checklist-value="location.code" checklist-change="auctionSelectionChanged()" id="{{location.code}}"> {{location.displayName}} </label> $scope.onLocationSelectionClicked = function($event) { if($scope.limitSelectionCountTo && $scope.selectedAuctions.locations.length == $scope.limitSelectionCountTo) { $event.currentTarget.checked=false; } };