【问题标题】:rerender Backbone views without losing references to dom在不丢失对 dom 的引用的情况下重新渲染 Backbone 视图
【发布时间】:2013-02-14 08:57:45
【问题描述】:

我的骨干有以下问题,我想知道哪种策略更合适

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

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

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

当获取操作最终准备就绪时,我使用从集合中加载的所有选项重新渲染控件。

为了渲染视图,我使用了这样的东西:

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

相当标准的骨干材料

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

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

所以我想知道在不丢失视图内对 dom 元素的所有引用的情况下重新渲染视图的最佳方法是什么...

【问题讨论】:

  • 我的 2 美分...你永远不应该直接使用 model.attributes,这就是为什么你有 model.get('something') 和 model.set('something', value) 或模型。设置({一些:a,事物:b})。
  • 仅使用 model.attributes 阅读有什么问题?我明白为什么我应该使用 Model#Set (来触发更改事件和其他东西),但 Model#Get 并没有做太多。看看代码,它只是一个:return this.attributes[attr];
  • 而且,据我所知,没有model.getAll()。 model.attributes 似乎是这样做的唯一方法。
  • 在某些时候你的程序员会使用“model.attributes”而不是“model.set”来编写,因为你缺乏一致性。
  • @opensas 为了让“属性”不可见(因为它主要供内部使用),我们执行以下操作:`render: function() { this.$el.html(this .template(this.model.toJSON()));返回这个; } `

标签: backbone.js view rendering


【解决方案1】:

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 元素是否被交换,因为其他视图不应该知道元素的存在。如果您定义视图之间的接口(通过方法调用或中介消息传递),您的应用程序将更易于维护且不那么脆弱。

【讨论】:

  • 优秀答案fencliff!!!这应该在视图的主干.js 定义中正确。我认为这些(不是那么)小的概念性的东西是让骨干很难开始的原因。
  • 因此,作为一般规则,我应该只使用对圆顶元素的引用: 1. 在构造函数中传递 el 元素时。 2. 从视图本身引用任何 dom 子树元素(我想我也应该覆盖 View#setElement 以更新所有内部引用)。 3. 无处可去 - 这样我可以在每次渲染时破坏 dom 视图并重新生成它,而不必担心损坏的 dom 引用(事实上,视图应该负责更新它们的内部引用)。你同意这样的规定吗?
猜你喜欢
  • 1970-01-01
  • 2017-12-31
  • 2020-02-04
  • 1970-01-01
  • 2022-06-10
  • 2016-07-22
  • 2017-04-09
  • 2018-03-27
  • 1970-01-01
相关资源
最近更新 更多