所以我有一个确认按钮:
<confirm-button class-name="btn-primary"
text="Save"
body="A customer with the same Last Name is already associated with this Company. Do you want to create this customer anyway?"
action="vm.save(false)"
place="bottom"></confirm-button>
这是一个自定义指令:
.directive('confirmButton', function () {
return {
restrict: 'E',
replace: true,
scope: {
text: '@',
className: '@',
action: '&'
},
controller: function ($scope, $element, $attrs) {
var content = $attrs.body ? '<p>' + $attrs.body + '</p>' : '';
var place = $attrs.place ? $attrs.place : 'top';
var rndEleId = 'BtnId' + Math.random().toString(36).slice(2);
var popoverOpts = {
title: $attrs.title || 'Are you sure?',
placement: place,
html: true,
content: content +
'<div class="centered">' +
'<button id="yes' + rndEleId + '" name="yes' + rndEleId + '" type="button" class="btn btn-primary btn-small" data-result="yes"><i class="icon-ok"></i> Yes</button>' +
' ' +
'<button id="no' + rndEleId + '" name="no' + rndEleId + '" type="button" class="btn btn-warning btn-small" data-result="no"><i class="icon-ban-circle"></i> No</button>' +
'</div>'
};
$element.popover(popoverOpts)
.parent()
.delegate('button',
'click',
function(e) {
e.preventDefault();
var el = $(e.currentTarget);
var result = el.data('result');
$element.popover('hide');
if (result === 'yes') {
$scope.$apply($scope.action);
}
}
);
},
template: '<a href="" class="btn {{className}}">{{text}}</a>'
};
})
我在页面上有这个按钮两次:一次在页面顶部,一次在底部。无论您单击哪一个,当单击是或否按钮时,它们会触发两次。这意味着按钮Action属性中的Save方法被调用两次。如果您正在更新记录,那不是一件可怕的事情,但如果您正在创建记录......它会被创建两次。
我使用了Chrome的开发人员工具,并在指令的e.preventDefault();
行放置了一个断点,当然,它会被击中两次。
但是,只有在页面上使用了多个指令时才会发生这种情况。如果我只有一个按钮(在页面的顶部或底部),e.preventDefault();
断点只会被击中一次。此外,它似乎是多线程的。我把一个计数器变量放在一个点上,旧学校的理论是“将它设置为0,然后将其设置为++,并检查它是否现在为1.如果它大于1,则不要执行操作如果等于1,则执行操作。“并且变量...每次都是新创建的,因此永远不会超过1。
我受到了阻碍。
答案 0 :(得分:1)
您还没有真正问过直接问题,但似乎您想知道为什么正在发生这种情况。
之所以发生这种情况,是因为您每次指令加载时都会向指令的父级添加一个click事件监听器。因此,当您在同一页面上有两个这样的指令时,您单击了按钮并且事件被触发两次,因为已注册了2个事件侦听器。下面是使用delegate
方法注册事件监听器的地方:
$element.popover(popoverOpts)
.parent()
.delegate('button',
'click',
function(e) {
...
首先,您需要确保自行清理并在指令被销毁时取消绑定您的事件监听器(请查看文档中的life-cycle hooks) 。下面是一个快速示例,说明如何在指令被销毁时取消绑定事件监听器:
// ...
// register your popover here
$element.popover(popoverOpts);
// reference your parent
var parent = $element.parent();
// reference your click function
var handleClick = function(e) {
e.preventDefault();
var el = $(e.currentTarget);
var result = el.data('result');
$element.popover('hide');
if (result === 'yes') {
$scope.$apply($scope.action);
}
}
// register your event listener
parent.on('click', handleClick);
// when your directive get's destroyed you need to unbind the `handleClick` function
$scope.$on('$destroy', function(e) {
parent.off('click', handleClick);
});
// ...
要解决您的问题,您需要确保注册事件监听器以满足您的需求。您可以阅读有关事件监听器here的更多信息。
虽然说实话,看看你的代码,你应该试试ui-bootstrap
。