Javascript 确认按钮事件触发两次
所以我有一个确认按钮:Javascript 确认按钮事件触发两次,javascript,jquery,angularjs,Javascript,Jquery,Angularjs,所以我有一个确认按钮: <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
<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>'
};
})
指令('confirButton',函数(){
返回{
限制:'E',
替换:正确,
范围:{
正文:“@”,
类名:“@”,
行动:'&'
},
控制器:函数($scope、$element、$attrs){
var content=$attrs.body?''+$attrs.body+'':'';
变量位置=$attrs.place?$attrs.place:'top';
var rndEleId='BtnId'+Math.random().toString(36).slice(2);
变量popoverOpts={
title:$attrs.title | |“你确定吗?”,
地点:地点,,
是的,
内容:内容+
'' +
“是的”+
' ' +
“不”+
''
};
$element.popover(popoverOpts)
.parent()
.delegate('按钮',
“点击”,
职能(e){
e、 预防默认值();
var el=$(e.currentTarget);
var结果=el.数据(“结果”);
$element.popover('hide');
如果(结果==‘是’){
$scope.$apply($scope.action);
}
}
);
},
模板:“”
};
})
我在页面上有两个按钮:一个在页面顶部,一个在底部。无论单击哪一个按钮,当单击“是”或“否”按钮时,它们都会触发两次。这意味着按钮操作属性中的Save方法将被调用两次。如果你正在更新一个记录,这不是一件可怕的事情,但是如果你正在创建一个记录。。。它被创建了两次
我使用了Chrome的开发工具,并在e.preventDefault()上放置了一个断点代码>指令中的行,而且确实,它会被命中两次
但只有当页面上使用了多个指令时,才会发生这种情况。如果我只有一个按钮(在页面的顶部或底部),则e.preventDefault()代码>断点只命中一次。此外,它似乎是多线程的。我在某一点上加入了一个反变量,使用了老派的理论“将其设置为0,然后将其设置为++,然后检查它现在是否为1。如果它大于1,则不执行该操作。如果它等于1,则执行该操作。”变量。。。每次都是新创建的,因此不会增加到1以上
我被难住了。您并没有真正提出一个直接的问题,但您似乎想知道为什么会发生这种情况。
之所以发生这种情况,是因为每次加载指令时,您都要向指令的父级添加一个单击事件侦听器。因此,当您在同一页面上有两个指令时,您单击了按钮,事件被触发两次,因为注册了两个事件侦听器。此处是使用以下方法注册事件侦听器的位置:
首先,当指令被破坏时,您需要确保自己进行清理,并解除事件侦听器的绑定(请查看文档)。下面是一个快速示例,说明在指令get被破坏时如何解除事件侦听器的绑定:
// ...
// 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);
});
// ...
要解决您的问题,您需要确保您正在注册事件侦听器以满足您的需要。您可以阅读有关事件侦听器的更多信息
虽然说实话,看看你的代码,你应该试一试。不确定你是否知道,但是有一个popover()的本机实现。如果你提供一个带有复制错误的JSFIDLE或PLUNK,找到解决方案可能会更容易。@Alon Eitan-实际上,这就是指令中的内容。它从Angular开始使用popover实现,并将其扩展为确认对话框。@PKD Cool,请注意,您可以使用自定义模板(在示例中)实现它,并且可以使用ngClick
将单击事件绑定到按钮Bootstrap 2.3.2是否存在相同的popover实现?遗憾的是,我现在无法升级应用程序中的引导版本。“为什么”正是我希望回答的问题。另外,我使用的是Bootstrap,但是2.3.2(有一个很长很长的故事,关于为什么网站不在最新版本上,但这需要很长时间才能进入)没有以一种令人愉快的方式处理事情。这很好,不使用ui Bootstrap没有什么错,只要确保你清理了你的侦听器,否则你会有内存泄漏。我在你的代码中注意到你丢失了“popoverOpts”。。。这些选项是如何进入你的POPORE的?你仍然需要传递你的POPopOPT,你可以单独做或者将它链接到 var父= $Eng.PopOver(POPOUPopts)PARTRONE()中;代码>-我已经更新了上面的答案以包含该部分
// ...
// 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);
});
// ...