重新渲染Backbone视图而不会丢失对dom的引用

时间:2013-02-14 08:57:46

标签: backbone.js view rendering

我对骨干有以下问题,我想知道什么策略是更合适的

我有一个选择控件,实现为Backbone视图,最初加载一个选项说“加载选项”。所以我加载一个只有一个元素的数组,然后渲染视图。

选项将从集合中加载,因此我会触发一个fetch集合。

然后我初始化一个负责显示每个字段的行错误的组件。所以我保存了组合的dom元素的引用。

当fetch操作最终准备就绪时,我会使用从集合中加载的所有选项重新呈现控件。

为了呈现视图,我使用了类似这样的视图:

render: function() {
  this.$el.html(this.template(this.model.attributes));
  return this;
}

相当标准的主干内容

问题是,在第二次渲染视图后,dom的引用不再有效,

也许这种情况有点奇怪,但我可以想到很多情况下我必须重新渲染视图而不会丢失他们的doms引用(例如,依赖于另一个组合的组合)

所以我想知道重新渲染视图的最佳方法是什么,而不会丢失视图中对dom元素的所有引用...

1 个答案:

答案 0 :(得分:5)

Backbone.View的目的是将对某个DOM子树的访问封装到一个定义良好的类中。传递DOM元素的引用是一个糟糕的Backbone实践,这些应该被视为视图的内部实现细节。

相反,您应该让您的观点直接沟通,或通过调解员间接沟通。

直接沟通可能类似于:

var ViewA = Backbone.View.extend({
  getSelectedValue: function() {
    return this.$(".combo").val()
  }
});

var ViewB = Backbone.View.extend({
  initialize: function(options) {
    this.viewA = options.viewA;
  },
  doSomething: function() {
    var val = this.viewA.getSelectedValue();
  }
});

var a = new ViewA();
var b = new ViewB({viewA:a});

间接使用根Backbone对象作为调解器:

var ViewA = Backbone.View.extend({
  events: {
    "change .combo" : "selectedValueChanged"
  },
  selectedValueChanged: function() {
    //publish
    Backbone.trigger('ViewA:changed', this.$('.combo').val());
  }
});

var ViewB = Backbone.View.extend({
  initialize: function(options) {
    //subscribe
    this.listenTo(Backbone, 'ViewA:changed', this.doSomething);
  },
  doSomething: function(val) {
    //handle 
  }
});

var a = new ViewA();
var b = new ViewB();

当然,上述内容非常通用,但我在此尝试说明的一点是,您不必担心DOM元素是否被交换,因为其他任何视图都不应该知道元素的存在。如果您定义视图之间的接口(通过方法调用或中介消息传递),您的应用程序将更易于维护且不那么脆弱。