Javascript AngularJS:动态绑定点击指令被多次触发
我尝试动态添加字段,并在指令的Javascript AngularJS:动态绑定点击指令被多次触发,javascript,jquery,angularjs,angularjs-directive,angularjs-scope,Javascript,Jquery,Angularjs,Angularjs Directive,Angularjs Scope,我尝试动态添加字段,并在指令的链接函数中绑定单击事件。但当我添加更多字段时,它似乎会多次开火。请参见下面的示例- var点击次数=0; var app=角度模块('测试',[]); 应用程序指令('control',函数($compile){ 变量链接器=函数(范围、元素、属性){ html('Button'+scope.count+''); 元素绑定('单击',函数(){ 点击++; $('#clicks').html('Clicked'+clicks+'times')) }); $comp
链接
函数中绑定单击
事件。但当我添加更多字段时,它似乎会多次开火。请参见下面的示例-
var点击次数=0;
var app=角度模块('测试',[]);
应用程序指令('control',函数($compile){
变量链接器=函数(范围、元素、属性){
html('Button'+scope.count+'');
元素绑定('单击',函数(){
点击++;
$('#clicks').html('Clicked'+clicks+'times'))
});
$compile(element.contents())(范围);
};
返回{
限制:'E',
范围:{
计数:'@'
},
链接:链接器
}
});
app.controller('TestController',函数($scope,$compile){
$scope.count=1;
$scope.addControl=函数(){
$(“#内容”)。追加(“”);
$compile($('#content').contents())($scope);
};
});代码>
#内容{
边缘顶部:10px;
}
#咔哒声{
边缘顶部:10px;
}
p{
颜色:灰色;
}
添加按钮
添加多个按钮,然后单击开头添加的按钮。请注意,单击次数将增加多次
例如,添加一组按钮,然后单击按钮1
,您需要以角度思考
只需像这样重写链接函数
var linker = function(scope, element, attrs) {
element.html('<button ng-click="onClick()" style="background:grey;">Button ' + scope.count + ' Clicked {{clicks}} times</button>');
scope.clicks=0;
scope.onClick = function(){
scope.clicks+;
}
$compile(element.contents())(scope);
};
var linker=函数(范围、元素、属性){
html('Button'+scope.count+'Clicked{{clicks}}次');
scope.clicks=0;
scope.onClick=function(){
范围.点击+;
}
$compile(element.contents())(范围);
};
您正在绑定单击事件两次,
因为指令在链接阶段被初始化了两次,点击处理程序在链接阶段被绑定,所以您通过$compile(element.contents())(scope)触发了摘要循环
哪个事件附加到指令,因为它们处于链接阶段,但事件可以绑定多次,所以指令有多个单击事件,第一个建议是先解除绑定事件
element.unbind('click').bind('click');
您可能会问,元素可能有多个单击事件,这是如何发生的
//event1
document.body.onclick = function(){ console.log('event1'); }
//event2
var oldClick = document.body.onclick;
document.body.onclick = function(){ console.log('event2'); oldClick.bind(document.body).call(); }
//this will trigger
event2
event1
工作样本如下
var点击次数=0;
var app=角度模块('测试',[]);
应用程序指令('control',函数($compile){
变量链接器=函数(范围、元素、属性){
html('Button'+scope.count+'');
元素。取消绑定('click')。绑定('click',函数(){
点击++;
$('#clicks').html('Clicked'+clicks+'times'))
});
$compile(element.contents())(范围);
};
返回{
限制:'E',
范围:{
计数:'@'
},
链接:链接器
}
});
app.controller('TestController',函数($scope,$compile){
$scope.count=1;
$scope.addControl=函数(){
$(“#内容”)。追加(“”);
$compile($('#content').contents())($scope);
};
});代码>
#内容{
边缘顶部:10px;
}
#咔哒声{
边缘顶部:10px;
}
p{
颜色:灰色;
}
添加按钮
添加多个按钮,然后单击开头添加的按钮。请注意,单击次数将增加多次
例如,添加一组按钮并单击按钮1
问题在于您多次编译#content
DOM,因为您的旧元素再次绑定到它。如果仔细观察,您将看到第n个按钮绑定了n-1
单击事件
下面是解释
当您添加第一个按钮时,它会添加它并编译第一个按钮
- 现在,
#content
有一个按钮,它绑定了一个click事件
当您添加第二个按钮时,它会被添加到DOM中,但它会重新编译整个#内容
DOM,您知道它已经有了一个带有click事件的按钮。当您#content
DOM时,它将再次重新编译第一个指令,并将再次向其添加click事件。它还将单击“事件到第二个”按钮
- 现在
#content
有2个按钮
- 第一个按钮有两个绑定到它的事件
- 第二个按钮有1个绑定到它的事件
当您添加第三个按钮时,您将看到下面的更改
- 现在
#content
有2个按钮
- 第一个按钮有3个绑定到它的事件
- 第二个按钮有两个绑定到它的事件
- 第三个按钮有一个绑定到它的事件
我想说的是,不要每次都通过重新编译DOM,自己在表单上呈现控件。假设您在页面上添加了第100个控件,因为您无缘无故地重新编译99
控件,这在技术上是没有意义的。因此,最好将渲染控件的责任交给ng repeat
标记
<div ng-controller="TestController">
<button ng-click="addControl()">Add Button</button>
<div ng-repeat="control in controls"><control count="{{control}}"></control></div>
<div id="clicks"></div>
</div>
我认为这不是解决办法。我明白我做错了什么。每次我添加一个控件时,我都会重新编译它的父控件的内容。我认为,您需要以angular
的方式进行思考。在angular
代码中使用jQuery
是一种糟糕的做法。为什么我的答案没有被打分/投票?有什么想法/建议吗?我可以知道它背后的原因吗?请添加注释,以便我知道哪里出了问题,从而改进我。@Medttleukuly问题在于每次创建新控件时我都在编译#content
(正如Pankaj所指出的)。尽管解绑有效,但我不认为这是解决我问题的实际办法。@AswinRamakrishnan,但我不明白为什么我的答案会被否决?你有什么想法吗:(你只有元素。解除绑定('click')。绑定('click');
这部分是正确的..但解释不中肯..你能看看我的答案吗..你会更好地了解它为什么会发生。谢谢:-)我编辑了我的答案,更详细一点。如果你什么都不懂,请告诉我。我是说你对我答案的编辑会很棒
app.controller('TestController', function($scope, $compile) {
$scope.count = 1;
$scope.controls = [];
$scope.controlsCount = 0;
$scope.addControl = function() {
$scope.controls.push(++$scope.controlsCount);
};
});