所以我在我的骨干应用程序中遇到了同样着名的僵尸视图问题。我试着成为超级英雄:P
var Router=Backbone.Router.extend({
routes:{
"":"loadDashboard",
"home":"loadDashboard",
'post-leads':"loadPostLeads"
},
initialize:function(){
window.currentView=null;
},
loadPostLeads:function(){
require(['views/post-leads'],function(leads){
if(window.currentView!=null)
{window.currentView.remove();}
window.currentView=new leads();
window.currentView.render();
})
},
loadDashboard: function(){
require(['views/dashboard'],function(dashboard){
if(window.currentView!=null)
{window.currentView.remove();}
window.currentView=new dashboard();
window.currentView.render();
})
}
});
这不起作用。我想要一些简单的东西,并且不想为了这个缘故而使用木偶或任何类似的东西。上面出了什么问题?这是一种明智的做法吗?
答案 0 :(得分:3)
原则上你应该做什么,但有一些东西是Backbone无法清理的,因为它不知道它们。
首先,您应该确保使用最新版本的Backbone(0.9.9
或更新版本)。事件绑定代码已经有了一些改进,这使得View.remove
方法更容易进行所有必要的清理。
常见问题是:
聆听模特活动:
//don't use other.on (Backbone doesn't know how to clean up)
this.model.on('event', this.method);
//use this.listenTo (Backbone cleans up events when View.remove is called)
//requires Backbone 0.9.9
this.listenTo(this.model, 'event', this.method);
聆听视图范围之外的DOM事件:
//if you listen to events for nodes that are outside View.el
$(document).on('event', this.method);
//you have to clean them up. A good way is to override the View.remove method
remove: function() {
$(document).off('event', this.method);
Backbone.View.prototype.remove.call(this);
}
直接参考:
//you may hold a direct reference to the view:
this.childView = otherView;
//or one of its methods
this.callback = otherView.render;
//or as a captured function scope variable:
this.on('event', function() {
otherView.render();
});
<强>闭包强>:
//if you create a closure over your view, or any method of your view,
//someone else may still hold a reference to your view:
method: function(arg) {
var self = this;
return function() {
self.something(x);
}
}
避免以下陷阱应该有助于您的观点得到正确清理。
根据评论进行修改:
啊,你没有在你的问题中提到完整的问题。正如我所说,你的方法的问题是你试图将两个视图渲染到同一个元素中:
var View1 = Backbone.View.extend({el:"#container" });
var View2 = Backbone.View.extend({el:"#container" });
当您删除View1
时,View2
无法正确呈现。
您应该将视图渲染为元素,而不是指定视图el
。在您的页面上,您应该有一个#container
元素,并将视图的元素追加到容器中。
loadPostLeads: function () {
var self = this;
require(['views/post-leads'], function (leads) {
self.renderView(new leads());
})
},
loadDashboard: function () {
var self = this;
require(['views/dashboard'], function (dashboard) {
self.renderView(new dashboard());
})
},
renderView: function(view) {
if(window.currentView) {
window.currentView.remove();
}
//the view itself does not specify el, so you need to append the view into the DOM
view.render();
$("#container").html(view.el);
window.currentView = view;
}