Backbone.js - 删除所有子视图
我有一个顶级的PageView,当路由发生变化时它会重新呈现自己。我有许多嵌入到此PageView中的嵌套子视图。如果我要重新呈现PageView,是否需要将所有嵌套的子视图与PageView一起移除/解除绑定,还是只需要移除/解除绑定PageView?如果我需要删除/取消绑定所有子视图,那么执行此操作的最佳方法是什么?Backbone.js - 删除所有子视图
是的,你需要正确地删除和解除绑定他们:
最简单的方式做,这是存储在父视图的子视图数组。然后,在父视图,遍历数组close
方法,并呼吁对孩子意见close
方法:
ParentView = Backbone.View.extend({
initialize: function(){
this.childViews = [];
},
render: {
for (var i = 0; i < 10; i++){
var childView = new ChildView();
// do stuff with the child view
this.childViews.push(childView);
}
},
close: function(){
this.remove();
this.unbind();
// handle other unbinding needs, here
_.each(this.childViews, function(childView){
if (childView.close){
childView.close();
}
})
}
});
一定要调用close
方法父视图,当你准备好了要删除/替换。这将确保所有的孩子都得到适当的清理(假设他们都有自己的close
方法)。
嘿德里克,我遵循你的建议,但是在关闭视图+它是子视图时,我经历了很长时间的延迟。在某些情况下,它可能长达5-10秒。看来延迟来自this.remove()。你知道为什么吗? – ragulka 2012-03-26 15:07:29
这是相当长,很糟糕!老实说,我从来没有见过这种情况......你要移除的DOM结构有多大?我唯一的猜测将是一个非常慢的浏览器,和/或一个非常大的DOM节点集。 – 2012-03-26 17:16:57
嘿,没关系 - 它似乎是一个jQuery插件的问题,而不是与视图的remove()函数冲突:http://stackoverflow.com/questions/9877786/calling-jquery-remove-on-custom-ui -widget-causes-infinite-loop/9878287#9878287 – ragulka 2012-03-26 19:29:55
而不是保留一个儿童数组视图,可以遍历视图的所有属性,看看哪些是Backbone.View的一个实例;您需要确保在父视图中为每个子视图设置一个属性。
在下面的示例中,子视图设置为父视图的属性。我不确定在所有属性中循环的性能会如何,但是,跟踪子视图的单独数据结构可能更容易。
例子:
var ContextView = Backbone.View.extend({
initialize: function() {
// views render themselves via their initialize methods
this.titlebar = new TitlebarView({el: $("#titlebar")});
this.toolbar = new ToolbarView({el: $("#toolbar")});
this.content = new ContentView({el: $("#content")});
},
removeChildViews: function() {
for(var prop in this){
if (this[prop] instanceof Backbone.View) {
console.log("This is a view: "+ prop + ' in ' + this[prop]);
}
}
},
render: function() {
this.$el.html(this.el);
}
});
一个简单的和模块化的类,你可能会发现有用。
ContainerView = Backbone.View.extend({
initialize: function() {
this.children = [];
},
remove: function() {
Backbone.View.prototype.remove.apply(this, arguments);
this.removeAllChildren();
},
removeAllChildren: function() {
_.each(this.children, function(view) { view.remove(); });
this.children = [];
},
appendAllChildren: function() {
_.each(this.children, function(view) { this.$el.append(view.render().$el); }, this);
}
});
用法:
MyView = ContainerView.extend({
render: function() {
this.removeAllChildren();
this.$el.empty();
// For each child view...
// this.children.push(new SomeControl(...));
this.appendAllChildren();
return this;
}
});
有点像Zengineer写的,我喜欢打补丁Backbone.View.remove全球像下面,使附着在这个孩子的任何意见被删除
var originalRemove = Backbone.View.prototype.remove;
Backbone.View.prototype.remove = function()
{
for (var view in this){
if (this[view] instanceof Backbone.View && this[view] != this) {
this[view].remove();
}
}
originalRemove.apply(this, arguments);
}
你是什么意思解除子视图?你的意思是事件吗? – Trevor 2012-03-02 00:19:33