我正在寻找写一条指令,该指令允许单击外部元素以克隆其包含的元素之一的ui-sref,以便单击外部元素的行为与单击.cloned元素的行为相同

<div clone-click=".cloned">
    ...
    <a class="cloned" ui-sref="root.a" ng-if="true">example</a>
    <a class="cloned" ui-sref="root.b" ng-if="false">example</a>
    ...
    <a ui-sref="root.c">elsewhere</a>
    ...
</div>


我尝试了触发点击的属性指令

app.directive('cloneClick', function() {
    return {
        restrict: 'A',
        scope: {
            selector: '@cloneClick'
        },
        link: function(scope, element) {
            element.click(function() {
                element.find(scope.selector).not(':disabled').first().click();
            })
        }
    };
})


但这会导致无限循环或其他原因,并且不起作用。我该如何运作?还是有更好的方法来实现这一目标?

最佳答案

您没有考虑事件冒泡。到目前为止,子级上的任何click事件都已经冒泡到父级,此时您要告诉它再次单击同一元素...从而无限循环(如果要单击的目标被单击)

我的建议是防止事件在<a>上传播。

如果单击了<a>本身,则让浏览器处理重定向,如果单击了父级的任何其他部分,请使用$location服务使用ui-sref生成的href值进行重定向。

就像是:

link: function(scope, element) {
  var $link = element.find(scope.selector).not(':disabled').first();
  // prevent bubbling on target link
  $link.click(function(e) {
    e.stopImmediatePropagation()
  });

  element.click(function(e) {
    // make sure target link wasn't element clicked
    if (e.target !== $link[0]) { // assumes no child tags in `<a>`
      $location.url($link.attr('href'));
    }
  });
}


您可能需要根据是否使用html5mode进行一些调整

编辑:我在写完这篇文章后想到,由于仍然可以防止事件传播(冒泡),因此您可以触发单击<a>而不是使用$location

09-16 10:37