Backbone.js在集合添加时触发两次渲染

时间:2012-04-19 12:38:36

标签: javascript backbone.js

在学习Backbone.js时,我正在使用Todos示例应用程序bundled with the latest version of Backbone(0.9.2)。我的问题是,为什么应用程序设计为在向Todos集合添加模型时触发渲染事件两次?

如果我将此行放在TodoView的渲染功能中:

// Re-render the titles of the todo item.
render: function() {
  console.log("Rendering!");
  this.$el.html(this.template(this.model.toJSON()));

然后“渲染!”在控制台中出现两次。我理解这是因为视图将模型的更改事件绑定到视图的渲染:

initialize: function() {
  this.model.bind('change', this.render, this);

在addOne中调用render,它绑定到Todos的add事件:

addOne: function(todo) {
  var view = new TodoView({model: todo});
  this.$("#todo-list").append(view.render().el);
},

但这是双重渲染设计的标准做法吗?看起来应该在创建(或进入DOM)时呈现视图,然后如果底层模型发生更改则再次呈现。在这种情况下,没有任何改变,但渲染被调用两次。

同样,我只是在学习Backbone,所以我可能会有一个基本的误解,导致我的困惑。

2 个答案:

答案 0 :(得分:5)

嗯,快看一下。你是对的,这种情况发生了,不是它不是标准做法。 原因有点模糊,所以忍受我;)

todo app正在使用backbone-localstorage。当您尝试在应用中添加新项目时,它会调用:

createOnEnter: function(e) {
  if (e.keyCode != 13) return;
  if (!this.input.val()) return;

  Todos.create({title: this.input.val()});
  this.input.val('');
},

注意Todos.create。通常,create会将模型添加到集合中,并将其保存在服务器上。因此将触发add事件。虽然backbone-localstorage在create上执行以下操作,但仍会发生这种情况:

create: function(model) {
  if (!model.id) model.set(model.idAttribute, guid());
  this.data[model.id] = model;
  this.save();
  return model;
},

请注意model.set为模型提供ID。这是触发(第二个)change事件的原因。

您可以通过将create更改为:

来阻止这种情况发生

if (!model.id) model.id = guid();

答案 1 :(得分:1)

重新渲染不应该发生。

尝试调试一点。尝试将更改事件绑定到包装器方法,如:

initialize: function(){
  this.model.bind( "change", this.renderWrapper, this );
}, 

renderWrapper: function(){
  console.log( "in the renderWrapper" );
  this.render();
}

确保为更改事件绑定设置了第二个render(),而不是出于其他原因。