【问题标题】:Angular js stop propagation from Bootstrap "dropdown-toggle" eventAngular js停止从Bootstrap“下拉切换”事件传播
【发布时间】:2017-06-06 14:15:32
【问题描述】:

我有一个 Angular JS 1.3 应用程序。

在其中我有一个带有 ng-click 的表格行中继器:

<tr ng-repeat-start="user in users.users" ng-click="showDetails = !showDetails">
 <!-- main row, with the menu td shown below -->
<tr class="row-details" ng-show="showDetails" ng-class="{ 'active': showDetails }">
    <td>this is the row that hows details</td>
</tr>
<tr ng-repeat-end></tr>

这会切换打开详细视图。工作正常。但是现在我需要在每个tds 中添加另一个项目,一个Bootstrap 按钮菜单:

<td>
<div class="btn-group">
  <div ng-switch on="user.status">
    <button class="btn btn-link btn-gear dropdown-toggle" type="button" data-toggle="dropdown"><i class="fa fa-cog"></i></button>

      <ul class="dropdown-menu dropdown-menu-right" role="menu" ng-switch-when="Inactive">
        <li><a href="" ng-click="users.modals.deleteUser()">Delete</a></li>
      </ul>

      <ul class="dropdown-menu dropdown-menu-right" role="menu" ng-switch-when="Invited">
        <li><a href="" ng-click="users.toast.resendInvite()">Resend invitation</a></li>
        <li><a href="" ng-click="users.modals.deleteUser()">Delete</a></li>
      </ul>

      <ul class="dropdown-menu dropdown-menu-right" role="menu" ng-switch-default>
        <li><a href="" ng-click="users.toast.sentPassword()">Reset password</a></li>
        <li><a href="" ng-click="users.modals.deleteUser()">Delete</a></li>
      </ul>
  </div>
</div>
</td>

问题是,尝试单击此菜单按钮会触发对行的 ng-click,切换行状态但从不打开我的菜单。我怎样才能防止这种情况发生?

【问题讨论】:

  • 每个 td 都有菜单按钮?
  • 是的。决定除了能够切换打开表格行的详细信息之外,还有一个“快速菜单”可以直接执行一些操作。
  • 你能提供更多关于 td 元素和下拉菜单的代码吗?
  • 我用更多代码充实了我的问题

标签: javascript angularjs twitter-bootstrap


【解决方案1】:

这是一个相当棘手的问题。问题是,当您单击菜单按钮时,会发生两件事:第一是它打开 Bootstrap 下拉菜单,第二是该事件传播到父元素并触发 showDetails = !showDetails

显而易见的解决方案是尝试在td 级别使用$event.stopPropagation() 停止事件传播,这样该事件就不会在DOM 树中冒泡,也不会触发父ngClick。不幸的是,它不起作用,因为 Bootstrap 在 document 元素上设置了点击事件侦听器以从冒泡中受益,因此您无法停止传播。

在这种情况下,我想出的最简单的解决方案是在原始事件对象上设置一个标志,无论事件是否发生在菜单按钮上。如果是这种情况,tr 上的ngClick 将不会做任何事情。

tr 看起来像这样:

<tr ng-repeat-start="user in users.users" ng-click="$event.originalEvent.dropdown || (showDetails = !showDetails)">

button 的回复:

<button ng-click="$event.originalEvent.dropdown = true" class="btn btn-link btn-gear dropdown-toggle" type="button" data-toggle="dropdown">
    <i class="fa fa-cog"></i>
</button>

演示: http://plnkr.co/edit/eIn6VW3Y2jHn0MtJQVcU?p=preview

【讨论】:

  • 天才。这很聪明。我永远不会猜测,谢谢。
  • 你我的朋友是个天才!这正是我所需要的,也是一个非常简单的解决方案!
【解决方案2】:

在 dfsq 的回答的帮助下,我设法解决了 Angular 2 中的同类问题。这是我的示例代码。

<td class="tablerowdata" (click)="$event.dropdown || onSelect(track)" >

<button (click)="$event.dropdown = true" type="button" class="btn btn-default dropdown-toggle trackbuttons" id="dropdownMenu1" data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-12-26
    • 2012-09-01
    • 2014-09-29
    • 1970-01-01
    • 1970-01-01
    • 2015-02-23
    • 2021-07-10
    • 2011-01-05
    相关资源
    最近更新 更多