2012-02-06 29 views
16

我想使用Underscore.js模板呈現Backbone.js集合作爲select列表,並且列表未被填充。 select元素正在顯示,但沒有options渲染Backbone.js集合作爲選擇列表

我已確認我可以將單個屬性傳遞到我的模板並將它們呈現爲label元素,所以問題一定是我如何處理集合。

這裏是我的骨幹代碼:

Rate = Backbone.Model.extend({ 
    duration : null 
}); 

Rates = Backbone.Collection.extend({ 
    initialize: function (model, options) { 
    } 
}); 

AppView = Backbone.View.extend({ 
    el: $('#rate-editor-container'), 
    initialize: function() { 
     this.rates = new Rates(null, { view: this }); 

     this.rates.add(new Rate ({ duration: "Not Set" })); 
     this.rates.add(new Rate ({ duration: "Weekly" })); 
     this.rates.add(new Rate ({ duration: "Monthly" })); 

     this.render(); 
    }, 
    render: function() { 
     var rate_select_template = _.template($("#rate_select_template").html(), {rates: this.rates, labelValue: 'Something' }); 
     $('#rate-editor-container').html(rate_select_template); 
    }, 
}); 

var appview = new AppView(); 

而且我的模板:

<script type="text/template" id="rate_select_template"> 
    <select id="rate-selector"></select> 
    <% _(rates).each(function(rate) { %> 
    <option value="<%= rate.duration %>"><%= rate.duration %></option> 
    <% }); %> 
</script> 

<div id="rate-editor-container"></div> 

有什麼建議?

+0

在渲染函數中仔細檢查'this'的值 - 我沒有看到你將它綁定到Backbone對象。你可以在你的初始化函數中用_.bindAll(this,'render')來完成它。 – 2012-02-06 01:15:15

+0

嗯。我在我的'Backbone.View'擴展中添加了'this.render()',但它似乎沒有做任何事情。在我發佈我的問題之前,我做了'console.log(this.rates)',並將它輸出爲具有三個子對象的'child'。所以我認爲我傳遞了一個嵌套在它下面的三個對象的某種對象,這看起來是正確的。 – 2012-02-06 01:19:43

+0

@Factor:在最近版本的Backbone中的'delegateEvents'自己完成綁定(查找'method = _。在[latest source](http://documentcloud.github.com/backbone/backbone.js)中綁定(method,this);''delegateEvents''內部,所以你不再需要通常的'_.bindAll'跳舞開始你的'initialize'方法。 – 2012-02-06 01:46:53

回答

34

你有幾個不同的問題。

  1. 您的模板是試圖把<option>元素<select>而不是它。這將產生無效的HTML,並且一旦你從你的模板中獲得任何東西,瀏覽器就會拋棄它。
  2. rates是Backbone集合,因此它已經可以訪問Underscore'seach;將它封裝爲_(rates)只是混淆了Underscore並防止發生任何迭代。
  3. 在迭代中,rate是一個Backbone模型實例,所以它不會有duration屬性,您必須說rate.get('duration')

你的模板應該看起來更像是這樣的:

<script type="text/template" id="rate_select_template"> 
    <select id="rate-selector"> 
     <% rates.each(function(rate) { %> 
      <option value="<%= rate.get('duration') %>"><%= rate.get('duration') %></option> 
     <% }); %> 
    </select> 
</script> 

演示:http://jsfiddle.net/ambiguous/AEqjn/

或者,你可以修復你的模板嵌套錯誤產生有效的HTML:

<script type="text/template" id="rate_select_template"> 
    <select id="rate-selector"> 
     <% _(rates).each(function(rate) { %> 
      <option value="<%= rate.duration %>"><%= rate.duration %></option> 
     <% }); %> 
    </select> 
</script> 

並在您的視圖中使用toJSON()將原始數據提供給您的模板而不是集合本身:

var rate_select_template = _.template($("#rate_select_template").html(), { 
    rates: this.rates.toJSON(), 
    labelValue: 'Something' 
}); 

演示:http://jsfiddle.net/ambiguous/VAxFW/

我認爲後者正是您作爲瞄準會更標準的方法來與骨幹模板工作。

+6

太棒了,謝謝你的明確解釋。不能相信我錯過了'select'嵌套的問題。啊。 Backbone.js似乎會很棒,但不可能找到像這樣一些真正基本的東西的例子。在todo應用程序等示例應用程序中有很多事情發生,並且很難看到每件作品的功能。我很感激幫助。 :) – 2012-02-06 02:17:06

+4

@Josh:一旦你弄清楚了基本模式,這是很好的,當然瞭解基本模式的唯一方法就是製作mistaeks。 – 2012-02-06 02:23:33