我在表格行上有一个点击事件,在这一行中还有一个带有点击事件的删除按钮。当我单击删除按钮时,该行上的单击事件也会被触发。
这是我的代码。
<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
事件?
ngClick 指令(以及所有其他事件指令)创建在同一范围内可用的 $event
变量。此变量是对 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>
Stewie 回答的补充。如果您的回调决定是否应该停止传播,我发现将 $event
对象传递给回调很有用:
<div ng-click="parentHandler($event)">
<div ng-click="childHandler($event)">
</div>
</div>
然后在回调本身中,您可以决定是否应该停止事件的传播:
$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>
请记住,这将阻止对最后一个单元格的所有点击,而不仅仅是按钮。如果这不是您想要的,您可能需要像这样包装按钮:
<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();
});
}
};
});
ngClick
,因为我实际上不想传播已处理的事件。
ignoreNgClick=true
这样的属性并处理它......以某种方式。理想情况下,在原始 ngClick
指令中,但修改它听起来很脏。
如果您使用像我这样的指令,当您需要两种数据方式绑定时,例如在更新任何模型或集合中的属性之后,它就是这样工作的:
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')
});
});
}
}
}
现在,您可以轻松地在任何按钮、链接、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;
}
};
ng-click
处理函数:ng-click="deleteUser(user.id, $event)"
。$event.preventDefault()
,否则在单击按钮时调用$event.stopPropagation()
会将我重定向到应用程序的根目录。