【发布时间】:2013-01-20 02:19:38
【问题描述】:
我有一个过滤器正在处理我的骨干集合。在搜索框中键入搜索并列出实时过滤器。效果很好,至少我是这么认为的。当我在 chrome 中查看内存堆快照时,我可以看到每次搜索都会泄漏内存... 6 megs 8 megs... 不久堆快照就超过了 100 megs。
我已在下面的视图中隔离了问题。如果我在初始化函数中注释掉 this.listenTo,我似乎不再泄漏内存。
所以我的问题是如何保持这些事件侦听器和集合上的实时过滤而不会泄漏。
var View = Backbone.View.extend({
tagName: 'tr',
initialize: function() {
this.listenTo(this.model, 'change', this.render);
this.listenTo(this.model, 'destroy', this.remove);
},
events: {
'click .edit': 'edit',
'click .delete': 'delete',
},
edit: function() { /* EDIT */ },
delete: function() {
this.model.destroy(); //backbone
},
render: function () {
var template = _.template( ProductTemplate )
this.$el.html( template({ this.model.toJSON() }) )
return this;
}
})
var ListView = Backbone.View.extend({
initialize: function()
{
this.collection = new Collection( Products ) //products are bootstrapped on load
},
render: function (terms)
{
this.$el.html( ListTemplate );
var filtered = Shop.products.collection.search(terms)
_.each(filtered, this.addOne, this)
//append list to table
$('#products').html( this.el )
return this
},
addOne: function (product)
{
this.$el.find('tbody').append(
new View({ model: product }).render().el
)
return this
},
});
var Collection = Backbone.Collection.extend({
model: Model,
search : function(letters){
//set up a RegEx pattern
var pattern = new RegExp(letters,"gi")
//filter the collection
return this.filter(function(model)
{
if(letters == "") return true //if search string is empty return true
return pattern.test(model.attributes['Product']['name'])
});
}
});
已解决:
这是我的新搜索方法。我不再过滤集合并重新渲染。我只是遍历集合,如果一个模型与搜索匹配,我们触发一个“显示”事件,如果它不在搜索中,我们触发一个“隐藏”事件。然后我们在视图中订阅这些事件并采取相应的行动。
集合中的搜索功能: 搜索:函数(查询){
//set up a RegEx pattern
var pattern = new RegExp(query,"gi")
//filter the collection
this.each(function(model){
if ( pattern.test(model.attributes['Product']['name']) ){
model.trigger('show')
}
else{
model.trigger('hide')
}
});
}
新观点: var ProductView = Backbone.View.extend({
tagName: 'tr',
initialize: function() {
this.listenTo(this.model, 'show', this.show);
this.listenTo(this.model, 'hide', this.hide);
},
hide: function()
{
this.$el.addClass('hide')
},
show: function()
{
this.$el.removeClass('hide')
},
render: function ()
{
var template = _.template( ProductTemplate )
this.$el.html( template( {data: this.model.toJSON(), Utils: Shop.utils} ) )
return this;
}
});
【问题讨论】:
-
所以你创建了很多
View实例,但从不调用remove? -
所以我知道我的问题是我正在创建无穷无尽的视图并且从不关闭它们。我只是想提出一种跟踪视图的好方法,以便我可以关闭它们。或者正如@anshr 下面建议的那样,根据查询简单地隐藏/显示它们。到目前为止,我一直没有使用这种方法。
标签: javascript backbone.js backbone-events