我正在寻找写一条指令,该指令允许单击外部元素以克隆其包含的元素之一的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