有没有办法将Model的.change()触发器绑定到View的.render()函数而不创建多个?

rkw*_*rkw 29 backbone.js

View通常需要具有这些属性的对象才能呈现:

{ el: '#someelement', model: someModel }
Run Code Online (Sandbox Code Playgroud)

View还允许我们将模型的事件绑定到视图中的函数:

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

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

renderFromModel: function() {
    var t = _.template($('#some-template').html());
    $('item-' + this.cid).html(t(this.toJSON()));
    return this;
},
Run Code Online (Sandbox Code Playgroud)

问题是我们第一次实例化一个View for rendering时,它期待一个带有Model的对象; 第二次从模型中调用它时渲染视图,它不是.因此,我最终创建了两个render()函数.

有没有更好的方法来实现单项渲染,也可以响应model.change()事件?

Der*_*ley 39

我认为您需要通过调用underscore.js的bindAll方法来确保您的render方法始终绑定到视图.

SomeView = Backbone.View.extend({
  initialize: function(){
    _.bindAll(this, "render");
    this.model.bind('change', this.render);
  },

  render: function(){
    $(this.el).html(this.template(this.model.toJSON()));
    return this;
  }
});
Run Code Online (Sandbox Code Playgroud)

  • 你可以使用这个.$ el而不是$(this.el):http://backbonejs.org/#View-$el(文档) (6认同)

Bla*_*nic 13

更好的解决方案是使用listenTo函数:

SomeView = Backbone.View.extend({
  initialize: function(){
    this.listenTo(this.model, 'change', this.render);
  },

  render: function(){
    this.$el.html(this.template(this.model.toJSON()));
    return this;
  }
});
Run Code Online (Sandbox Code Playgroud)

这样,视图对象就知道它所做的绑定,并且可以使用stopListening函数删除所有绑定,并且不需要显式调用bind或bindAll.最后但并非最不重要的是,我认为代码更清晰.


ant*_*_Ti 12

使用_.bind()方法设置范围

 this.model.bind('change', _.bind(this.render, this));
Run Code Online (Sandbox Code Playgroud)


myb*_*ael 6

作为骨干0.9.2(以及可能更早)时,on()bind()功能(以及其对应off()unbind())接受一个可选context参数,以用于this调用时.

所以,

SomeView = Backbone.View.extend({
  initialize: function(){
    _.bindAll(this, "render");
    this.model.bind('change', this.render);
  },

  render: function(){
    this.$el.html(this.template(this.model.toJSON()));
    return this;
  }
});
Run Code Online (Sandbox Code Playgroud)

可以变成

SomeView = Backbone.View.extend({
  initialize: function(){
    this.model.bind('change', this.render, this);
  },

  render: function(){
    this.$el.html(this.template(this.model.toJSON()));
    return this;
  }
});
Run Code Online (Sandbox Code Playgroud)

请参阅文档on().