我正在尝试制作我的第一个搜索应用。
构建应用程序后,每个DOM都按照我的预期呈现,事件也可以正常运行。当我深入研究它时,我发现了一个奇怪的行为,在我做了一些搜索之后,我发现这是因为 zombie view 事件委托问题。
以下是我的代码的一部分:
var searchList = Backbone.View.extend({
events:{
'click #submit':function() {
this.render()
}
},
render() {
this.showList = new ShowList({el:$('.ADoM')});
}
});
点击#submit
后,系统会创建ShowList
的新实例,并会呈现'.ADoM'
DOM。
showList.js
var showList = Backbone.View.extend({
events: {
"click .testing": function(e) {
console.log(e.currentTarget);
},
},
initialize() {
this.$el.html(SearchListTemplate());
}
});
'.testing'
按钮事件与其绑定。
正如'zombie'所做的那样,在多次点击提交后,点击'.testing'
按钮,console.log()
将输出多次。
我已按照文章here尝试了解并修复了我的问题,并尝试在this.remove()
中添加showList.js
,但不幸的是,因为我不是能够将它们放在我的代码中的适当位置,问题仍然没有解决。
答案 0 :(得分:1)
这与ES6无关,这是基本的JavaScript和DOM操作。
您正在创建绑定到页面中相同元素的新find
个实例。在Backbone中,这是不好的做法。
每个Backbone View实例都有自己的根元素,事件绑定在该根元素上。当多个视图共享同一个元素时,会在每个实例上触发事件,并且您无法在视图上调用remove
,因为它将完全从页面中删除DOM元素。
您应该将子视图根元素转储到您希望重用的元素中。
ShowList
render
函数应为idempotent。
this.$('.ADoM').html(this.showList.render().el);
您的其他视图也可以简化,以反映父视图中的更改。
var searchList = Backbone.View.extend({
events: {
// you can use a string to an existing view method
'click #submit': 'render'
},
initialize() {
// instanciate the view once
this.showList = new ShowList();
},
// This implementation always has the same result
render() {
this.$('.ADoM').html(this.showList.render().el);
// Backbone concention is to return 'this' in the render function.
return this;
}
});
这是重用视图而不是始终创建新视图的超级基本示例。
完成视图后,您应该在其上调用remove
:
从DOM中删除视图及其
的任何绑定事件var showList = Backbone.View.extend({ events: { "click .testing": 'onTestingClick', }, // Don't render in the initialize, do it in the render function render() { this.$el.html(SearchListTemplate()); }, onTestingClick(e) { console.log(e.currentTarget); } });
,然后调用stopListening
删除视图具有listenTo
'd。
为此,在模型或集合事件上注册回调时,use listenTo
over on
or bind
以避免其他内存泄漏(或僵尸视图)。
具有多个子视图的视图的一个好模式是保留每个子视图的引用,并在删除父视图时为每个子视图调用el
。
了解如何avoid memory leaks when rendering list views。在处理大量视图(大列表或视图树)时,有efficiently render with Backbone方法涉及DocumentFragment批处理和推迟。