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$event
variables,它在相同的作用域上可用。 这个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; } };