2011-08-16 51 views
28

的視角通常希望使用這些屬性的對象,然後才能呈現:有沒有辦法將Model的.change()觸發器綁定到View的.render()函數而不創建多個?

{ el: '#someelement', model: someModel } 

的視角也讓我們模型的事件綁定到功能視圖:

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

的問題是,我們第一次實例化一個視圖進行渲染時,它期待着一個帶有模型的對象;第二次在模型中調用視圖時,它不是。因此,我最終創建了兩個render()函數。

是否有更好的方法來實現單個項目渲染,也可以響應model.change()事件?

回答

38

我認爲你需要確保你的render方法總是通過調用underscore.js的bindAll方法來綁定視圖。

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

哦,geeze,謝謝!我想我真的需要閱讀underscore.js – rkw

+6

你可以使用這個。$ el而不是$(this.el):http://backbonejs.org/#View-$el(文檔) – Fabdrol

12

使用_.bind()方法來設置範圍

this.model.bind('change', _.bind(this.render, this)); 
+1

謝謝ant_Ti。我一遍又一遍地閱讀文檔,但它仍然逃避我的理解。這是如何起作用的? – rkw

+0

我覺得 this.model.bind(「change」,this.render,this)的行爲; 和 this.model.bind('change',_.bind(this。渲染,這)); 是不同的,雖然第一個也定義了這個範圍,但在我的情況下,ant_Ti建議工作 –

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

可以成爲

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

the documentation for on()

+0

@ muistooshort是的!接得好。我從上面的答案複製和粘貼(顯然有點舊)。 – mybuddymichael

0

視圖

var myapp.myView = new View({ 
     model: new Model 
    }); 

創建模型的實例,當你初始化Backbone.View裏面添加這個..這使將被稱爲隨時有變化的模型屬性從它的默認值

this.model.bind('change', this.render,this) 
13

更好的解決方案是使用listenTo function

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

通過這種方式,視圖對象知道它所做的綁定,並且所有這些都可以使用stopListening function刪除,並且不需要顯式調用bind或bindAll。最後但並非最不重要的代碼在我看來更清潔。

+0

不應該是另一個評論中提到的「this。$ el.html」嗎? –

+0

已更新,謝謝 – Blacksonic

+0

也許這是針對BackboneJS的更新版本,但是您是否也必須在'render'屬性中設置函數的上下文?也就是說,你必須在視圖的'initialize'屬性中添加'_.bindAll(this,'render')'。 – sameers

相關問題