我正在尝试编写一些Javascript对象来管理页面上的动态表单。
forms对象为表单存储一个数组并将它们呈现到容器中。
我希望每个表单上的某些字段都有点击事件,因此决定创建一个单独的对象并尝试在对象init
方法中绑定一个事件。
对于我添加的每个新表单,都明显触发了init方法。但是在更改事件时,只会触发我的数组中的最后一个表单对象。
JS小提琴演示问题
可以找到:here
function Form(node) {
this.node = node;
this.init = function() {
$(this.node).find("input:checkbox").change(event => {
console.log('Event fired');
});
};
this.init();
}
// Object to manage addition / removal
var forms = {
init: function() {
this.formsArray = [];
this.cacheDom();
this.bindEvents();
this.render();
}
// Only selector elems from the DOM once on init
cacheDom: function() { ... },
// Set up add / remove buttons to fire events
bindEvents: function() { ... },
render: function() {
for (let form of forms)
this.$formSetContainer.append(form.node)
}
addForm: function() {
// Logic to create newRow var
this.formsArray.push(new Form(newRow));
},
removeForm: function() {
// Logic to check if a form can be removed
this.formsArray.pop();
}
},
我已经尝试过的事情
我实际上能够通过删除Form构造函数中的render
并像这样更改this.init()
来绑定render
内的事件:
for (let form of this.formsArray) {
this.$formSetContainer.append(form.node)
form.init();
}
然后事件将成功触发每个表单
但是我每次调用render()
时都不会运行此代码,每次添加/删除表单时都会调用它。
我有一种感觉,这是一个范围问题,或者事件在某种程度上被破坏了。无论是那个还是我误解了事件是如何约束的。任何指针都将不胜感激
答案 0 :(得分:1)
查看JSFiddle中的代码,问题来自于在render函数中使用this.$formSetContainer.empty()
。 .empty()从DOM节点中删除所有事件处理程序。
为了避免内存泄漏,jQuery会在删除元素本身之前从子元素中删除其他构造(如数据和事件处理程序)。
如果要在不破坏数据或事件处理程序的情况下删除元素(以便以后可以重新添加),请改用.detach()。
您可以将其替换为this.$formsetContainer.children().detach()
,它会执行您想要的操作。