如何克隆ui sref

How to clone ui-sref

本文关键字:sref ui 何克隆      更新时间:2023-09-26

我想写一个指令,允许点击外部元素来克隆其包含的元素之一的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();
            })
        }
    };
})

但这会导致一个无限循环或其他什么,并且不起作用。我怎样才能让它工作?或者有更好的方法来实现这一点吗?

您没有考虑事件冒泡。和现在一样,子元素上的任何单击事件都将冒泡到父元素上,此时您将告诉它再次单击同一元素。。。因此,如果你想要的目标被点击,就会出现无限循环

我的建议是防止事件在<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,因为事件传播(冒泡(仍然被阻止

<ANY clone-click=".is-clone-click:not(:disabled):not(.is-disabled)">
    <a class="is-clone-click" ui-sref="root.example">example</a>
</ANY>

我让它这样工作。一些禁用指针的元素可以通过将其容器设置为e.target来点击,所以我在这些容器上添加了.is-no-clone-click来忽略它们。

app.directive('cloneClick', function() {
    var angular = require('angular');
    var ignore = '[href], [ui-sref], [ng-click], .is-no-clone-click, label, input, textarea, button, select, option, optgroup';
    return {
        restrict: 'A',
        scope: {
            selector: '@cloneClick'
        },
        link: function (scope, element) {
            element.click(function(e) {
                if (e.isTrigger) {
                    return;
                }
                var cloned = element.find(scope.selector).first();
                var target = angular.element(e.target);
                if (cloned.length && !cloned.is(target) && !target.is(ignore)) {
                    cloned.click();
                }
            });
        }
    };
});

光标也可以通过鼠标悬停和类似的CSS类添加

element.mouseover(function() {
    element.toggleClass('is-pointer', !!element.has(scope.selector).length);
});

但我最终并没有使用这个指令,因为我能够创建一个CSS链接屏蔽解决方案来实际解决我想要做的事情。