我对uiSref指令有一个有趣的问题,但我一直无法在网络上的任何地方找到解决方案(无论如何都是一种优雅的解决方案)。基本上,我要求客户端能够单击资源表中的一行并转到该资源的编辑 View 。通常,uiSref指令可以很好地工作,但是问题出在以下事实:我在表的最后一个<td>中有一个Bootstrap下拉列表,其中有很多快速操作。 HTML看起来像这样:

<table class="table table-bordedered table-hover">
  <thead>
    <tr>
      <td>Name</td>
      <td>Actions</td>
    </tr>
  </thead>
  <tbody>
    <tr ng-repeat="resource in resources" ui-sref="edit({id: resource.id})">
      <td ng-bind="resource.name"></td>
      <td class="actions-column">
        <div class="btn btn-xs btn-default" data-toggle="dropdown">
          <i class="fa fa-cog"></i>
        </div>
        <ul class="dropdown-menu pull-right">
          <li>
            <a href="javascript:void(0)" ng-click="doSomethingCrazy(resource)">SOMETHING CRAZY</a>
          </li>
        </ul>
      </td>
    </tr>
  </tbody>
</table>

问题是,当我单击“操作”列中的按钮时,uiSref会覆盖下拉菜单的默认操作,并带我进入编辑页面。现在,您可能会问自己:“那很简单,为什么您不能仅停止事件的传播!?” ...不起作用。当我将此添加到“操作”列中时:
<td class="actions-column" ng-click="$event.stopPropagation()">

它终止了下拉菜单的功能,但未显示任何内容。现在,我有一个解决方法,可以在ngClick元素上定义一个<tr>,然后根据所单击的元素来确定状态应到达的位置,如下所示:
<tr ng-repeat="resource in resources" ng-click="goToEdit(resource, $event)">

JS看起来像这样:
scope.goToEdit = function(resource, event) {
  // if the event.target has parent '.actions-column' or is that column, do nothing else
  // invoke $state.go('edit', {id: resource.id})
}

我讨厌它,但是我有很多这样的 ListView 。我要寻找的是一个优雅且可移植的解决方案,希望可以像$event.stopPropagation()一样通过UI Router进行 native 工作(尽管我已经遍历了UI Router源,但似乎找不到可行的替代方案)。基本上,我也想吃蛋糕。无论如何,看到SO社区可以提出什么或者我目前无法实现的要求将是一件很有趣的事情。谢谢!

最佳答案

我知道了!在浏览UI路由器源代码时,如果在target所驻留的元素上填充了uiSref属性,则似乎单击事件将被忽略。它可能不是世界上最美丽的东西,但肯定比我以前做的要容易。

注意:仅在使用整个jQuery库而不是jQLite时才有效

所以我写了这个指令:

app.directive('uiSrefIgnore', function() {
  return {
    restrict: 'A',
    link: function(scope, elem, attrs) {
      elem.on('click', function(e) {
        // Find the ui sref parent
        var uiSref = elem.parents('[ui-sref]').first();
        // Set the target attribute so that the click event is ignored
        uiSref.attr({
          target: 'true'
        });
        // Function to remove the target attribute pushed to the bottom
        // of the event loop. This allows for a digest cycle to be run
        // and the uiSref element will be evaluated while the attribute
        // is populated
        setTimeout(function() {
          uiSref.attr({
            target: null
          });
        }, 0);
      });
    }
  };
});

这样,每当我只想忽略uiSref指令的javascript事件时,都可以将其添加到html中:
<tr ui-sref="edit">
  <!-- any other elements -->
  <td ui-sref-ignore>The element I care about</td>
</tr>

繁荣!让我知道你们对这个含义的看法。

10-07 15:36