我渲染了一个模型集合,它与collectionView相关联,当渲染时,集合中的每个元素都有自己的'itemview'呈现。
当一个集合被排序并且listView根据新的顺序重新渲染时,我一直在为每个项目创建一个全新的视图,因为我没有清除与该模型相关的任何先前的视图实例,相信僵尸被留下来。
所以最初渲染我的收藏品我会做...
render : function() {
$(this.el).empty();
var content = this.template.tmpl({});
$(this.el).html(content);
sortingView.el ='#sorting-container';
var els = [];
_.each(this.collection.models, function(model){
var view = new TB_BB.RequestItemView({model : model});
els.push(view.render().el);
});
$('#request-list').append(els);
sortingView.render();
return this;
}
所以每当渲染函数被调用第二个/第三个等时,我都没有清理TB_BB.RequestItemView(因此是僵尸)
为了解决这个问题,我尝试在集合视图中添加一些简单的缓存,这样如果已经创建了一个新的项目视图而不是创建它,请使用它。我的代码
initialize : function(){
_.bindAll(this,"render");
this.collection.bind("add", this.render);
this.collection.bind("remove", this.render);
this.template = $("#request-list-template");
this.views = {};
},
events : {
"change #sort" : "changesort",
"click #add-offer" : "addoffer",
"click #alert-button" : "addalert"
},
render : function() {
$(this.el).empty();
outerthis = this;
var content = this.template.tmpl({});
$(this.el).html(content);
sortingView.el ='#sorting-container';
var els = [];
_.each(this.collection.models, function(model){
var view;
if(outerthis.views[model.get('id')]) {
view = outerthis.views[model.get('id')];
} else {
view = new TB_BB.RequestItemView({model : model});
outerthis.views[model.get('id')] = view;
}
});
$('#request-list').append(els);
sortingView.render();
return this;
}
所以这可以在重复使用视图的情况下工作 - 但是我注意到的是,如果我使用缓存视图(例如,集合已经排序并且渲染函数找到了缓存视图),那么所有的子项目视图上的事件停止工作?那是为什么?
也有人可以提出更好的方法吗?
答案 0 :(得分:3)
您可以使用delegateEvents(http://documentcloud.github.com/backbone/#View-delegateEvents)再次绑定事件。
答案 1 :(得分:0)
正如OlliM所提到的那样,原因是事件被绑定到dom元素,但是不是重新绑定元素,你也可以分离它们而不是删除它们(detach保持事件绑定http://api.jquery.com/detach/)
类似
var $sortContainer = $('#sorting-container');
$('li', $sortContainer).detach();
然后重新附加元素
$cnt.append(view.el);
我还会考虑在重建/排序列表时使用文档片段,然后附加附加的文档片段。