本文翻译自:AngularJS ng-click stopPropagation
I have a click Event on a table row and in this row there is also a delete Button with a click Event. 我在表行上有一个单击事件,在这一行中还有一个带有单击事件的删除按钮。 When i click the delete button the click Event on the row is also fired. 当我单击删除按钮时,也会触发该行上的事件。
Here is my code. 这是我的代码。
<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>
How can I prevent that the showUser
Event is fired when i click the delete Button in the table cell? 当我单击表格单元格中的删除按钮时,如何防止showUser
事件被触发?
#1楼
参考:https://stackoom.com/question/1NBBK/AngularJS-ng-单击stopPropagation
#2楼
ngClick directive (as well as all other event directives) creates $event
variable which is available on same scope. ngClick指令(以及所有其他事件指令)创建$event
变量,该变量在相同范围内可用。 This variable is a reference to JS event
object and can be used to call stopPropagation()
: 此变量是对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>
#3楼
An addition to Stewie's answer. Stewie的答案的补充。 In case when your callback decides whether the propagation should be stopped or not, I found it useful to pass the $event
object to the callback: 如果您的回调决定是否应停止传播,我发现将$event
对象传递给回调很有用:
<div ng-click="parentHandler($event)">
<div ng-click="childHandler($event)">
</div>
</div>
And then in the callback itself, you can decide whether the propagation of the event should be stopped: 然后在回调本身中,您可以决定是否应停止事件的传播:
$scope.childHandler = function ($event) {
if (wanna_stop_it()) {
$event.stopPropagation();
}
...
};
#4楼
<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;
}
};
#5楼
I wrote a directive which lets you limit the areas where a click has effect. 我写了一条指令,可让您限制点击有效的区域。 It could be used for certain scenarios like this one, so instead of having to deal with the click on a case by case basis you can just say "clicks won't come out of this element". 它可以用于诸如此类的某些情况,因此您不必说要逐案处理点击,而只需说“点击不会从这个元素中发出”。
You would use it like this: 您可以这样使用它:
<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>
Keep in mind that this would prevent all clicks on the last cell, not just the button. 请记住,这将阻止所有单击最后一个单元格,而不仅仅是按钮。 If that's not what you want you may want to wrap the button like this: 如果这不是您想要的,则可以像这样包装按钮:
<span isolate-click>
<button class="btn" ng-click="deleteUser(user.id, $index);">
Delete
</button>
</span>
Here is the directive's code: 这是指令的代码:
angular.module('awesome', []).directive('isolateClick', function() {
return {
link: function(scope, elem) {
elem.on('click', function(e){
e.stopPropagation();
});
}
};
});
#6楼
In case that you're using a directive like me this is how it works when you need the two data way binding for example after updating an attribute in any model or collection: 如果您使用的是像我这样的指令,例如在更新任何模型或集合中的属性后需要两个数据方式绑定时,这就是它的工作方式:
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')
});
});
}
}
}
Now, you can easily use it in any button, link, div, etc. like so: 现在,您可以轻松地在任何按钮,链接,div等中使用它,如下所示:
<button set-survey-in-edition-mode >Edit survey</button>