Backbone.js - 删除所有子视图

时间:2012-03-01 19:42:47

标签: backbone.js

我有一个顶级的PageView,它会在路线发生变化时重新渲染。我有很多嵌套在这个PageView中的嵌套子视图。如果我要重新渲染PageView,我是否需要删除/取消绑定所有嵌套的子视图以及PageView,还是只需要删除/取消绑定PageView?如果我需要删除/取消绑定所有子视图,那么最好的方法是什么?

4 个答案:

答案 0 :(得分:35)

是的,您需要正确删除和取消绑定它们:

http://lostechies.com/derickbailey/2011/09/15/zombies-run-managing-page-transitions-in-backbone-apps/

执行此操作的简单方法是在父视图中存储子视图的数组。然后在父视图的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方法)。

答案 1 :(得分:3)

您可能觉得有用的简单模块化课程。

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;
  }
});

答案 2 :(得分:2)

不是保留子视图数组,而是可以迭代视图的所有属性,看看哪些是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);
    }
  });

答案 3 :(得分:1)

有点像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);

}