我正在努力通过单页面应用程序获得内存管理的概念。这是我的代码:
var FilterModel = Backbone.Model.extend({});
var taskView = Backbone.View.extend({
template: _.template('<h1><%= title %></h1>'),
initialize: function(){
this.render();
this.listenTo(this.model, 'destroy', this.remove);
console.log(this.model)
},
render: function(){
this.$el.html(this.template(this.model.toJSON()));
return this;
},
events:{
'click h1': 'removeView'
},
removeView: function(){
this.model.destroy();
console.log('removed');
}
});
var filterModel = new FilterModel({title: 'Test'});
var taskview = new taskView({model:filterModel});
// I make heap snapshot before and after the change!
setTimeout(function(){
$("h1").click()}, 3000
)
$('body').append(taskview.$el);
许多文章都告诉我,使用“删除”和“销毁”会在删除DOM树时清除任何内存泄漏。
但Chrome个人资料实用程序则另有说法。无论我做什么,我都会得到分离的DOM元素。
UPDATE !!! 在回复中尝试了一些内容后,我仍然可以在Google Chrome中使用此功能: 这是jsfiddle:http://jsfiddle.net/HUVHX/
答案 0 :(得分:1)
所以Janck,你可以在这里找到答案: Backbone remove view and DOM nodes
问题是你必须做的不仅仅是移除模型和视图。
当您尝试关闭视图时,您需要正确销毁所有挂起的事件和其他绑定。
我不知道你是否知道 Marionette.js (Backbone.Marionette),但它是Backbone的一个很好的扩展来处理这个 Zombie Views 并创建健壮的JS应用程序。
您也可以阅读一些有关此内容的文章,我们在我发布的Stackoverflow链接中指出了它们。
http://lostechies.com/derickbailey/2012/03/19/backbone-js-and-javascript-garbage-collection/
但逻辑是这样的:如果View正在倾听模型,那么相反也会发生,所以您总是会在DOM中获得View的实例。
答案 1 :(得分:1)
要测试我的假设,只需添加:
removeView: function(){
this.model.destroy();
this.el = undefined;
this.$el = undefined;
}
另一种方法是undef taskview var
修改强>:
当我更改:"click h1" : "removeView"
到"click": "removeView"
它解决了分离的dom节点泄漏。
我怀疑这与jquery选择器缓存有关。
您可以在骨干代码中看到,区别在于使用选择器调用jquery on
函数:
if (selector === '') {
this.$el.on(eventName, method);
} else {
this.$el.on(eventName, selector, method);
}
我试图将缓存深入到jquery代码中,没有运气。