AngularJS ng-单击stopPropagation

mic*_*ght 424 javascript angularjs angularjs-ng-click

我在表行上有一个单击事件,在这一行中还有一个带有单击事件的删除按钮.当我单击删除按钮时,也会触发行上的单击事件.

这是我的代码.

<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>
Run Code Online (Sandbox Code Playgroud)

showUser当我单击表格单元格中的删除按钮时,如何防止触发事件?

Ste*_*wie 786

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>
Run Code Online (Sandbox Code Playgroud)

PLUNKER

  • @event对象是在ng-click指令内创建的,你可以将它传递给你的`ng-click`处理函数:`ng-click ="deleteUser(user.id,$ event)"`. (93认同)
  • 我不得不添加`$ event.preventDefault()`,否则调用`$ event.stopPropagation()`会在单击按钮时将我重定向到我的应用程序的根目录. (18认同)
  • 谢谢,有点想到那一个,但我认为它仍然很臭:) (6认同)
  • 我无法弄清楚控制器代码中是否有这个 - $ scope.$ event似乎没有用.有任何想法吗? (2认同)
  • 我认为执行这样的多个表达式是一个反模式.为什么不直接将$ event作为deleteUser()的第三个参数传递给该函数内的stopPropagation()? (2认同)
  • @djheru多个表达式似乎很笨拙,但在控制器中放置这种事件代码似乎很奇怪.我们可以通过在_parent_元素(在这种情况下为`td`)上放置`ng-click ="$ event.stopPropagation()"`来解决这两个问题. (2认同)

kor*_*rya 123

Stewie答案的补充.如果您的回调决定是否应该停止传播,我发现将$event对象传递给回调很有用:

<div ng-click="parentHandler($event)">
  <div ng-click="childHandler($event)">
  </div>
</div>
Run Code Online (Sandbox Code Playgroud)

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

$scope.childHandler = function ($event) {
  if (wanna_stop_it()) {
    $event.stopPropagation();
  }
  ...
};
Run Code Online (Sandbox Code Playgroud)

  • 这比在html属性中执行多个表达式更优雅,谢谢 (10认同)
  • 请记住在html ng-click指令中放入'$ event'参数.我起初偶然发现了这一点. (3认同)

Jen*_*ens 10

我写了一个指令,允许你限制点击有效的区域.它可以用于像这样的某些场景,因此您不必根据具体情况处理点击,而只是说"点击不会来自此元素".

你会像这样使用它:

<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>
Run Code Online (Sandbox Code Playgroud)

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

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

这是指令的代码:

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