2011-10-07 116 views
4

我有一個表像這樣Backbone.js的鏈接模型和視圖

<table> 
    <tr id="row-one" class="item-row"> 
    <td class="price"></td> 
    <td><input type="text" class="quantity" value="" /></td> 
    </tr> 
    <tr id="row-two" class="item-row"> 
    <td class="price"></td> 
    <td><input type="text" class="quantity" value="" /></td> 
    </tr> 
    <tr id="subtotal"> 
    <td id="subtotal"></td> 
    <td id="subquantity"></td> 
    </tr> 
</table> 

,我有了這個主心骨js代碼

<script type="text/javascript"> 
    jQuery(document).ready(function($){ 
    var Item = Backbone.Model.extend({ 
     initialize: function(){ 
     }, 
     defaults: { 
     price: 0, 
     quantity: 0 
     } 
    }); 
    var ItemsCollection = Backbone.Collection.extend({ 
     model : Item, 
     subquantity: function(){ 
     subquantity = 0; 
     this.each(function(item){ 
      subquantity += item.get('quantity'); 
     }); 
     return subquantity; 
     } 
    }); 
    var ItemView = Backbone.View.extend({ 
     events: { 
     "change .quantity": "updateQuantity" 
     }, 
     render: function(){ 
     alert('render'); 
     }, 
     updateQuantity: function(){ 
     this.model.set({quantity: this.$('.quantity').val()}); 
     console.log(this.model.get('quantity')); 
     } 
    }); 
    var totals = new ItemsCollection(); 
    var item_one = new Item({ price:1,quantity:10 }); 
    var item_two = new Item({ price:1,quantity:20 }); 
    totals.add(item_one); 
    totals.add(item_two); 
    var view_one = new ItemView({model:item_one,el:'.item-row'}); 
    }) 
</script> 

我的問題是操縱。

1)到目前爲止,我可以管理一行,沒關係。但是我想管理第二行。我是否只是實例化ItemView的另一個實例?或者我可以使用一個ItemView實例來管理多個Models?或更好的是,與Collection

2)我使用Collection來管理小計和子量。我是否創建一個單獨的視圖來管理DOM中的這些字段?或者我應該在集合中更新它們?

如果有人有任何其他提示,我很樂意聽到它。這是我第一次接觸骨幹,所以我只想盡可能多地瞭解信息。謝謝!

回答

14

與大多數骨幹問題一樣,對此沒有「正確的」答案 - 您需要找出最適合您的方法,這部分取決於您的應用程序可能有多複雜得到。

在你的設置中,我覺得很奇怪的主要原因是你已經硬編碼你的表來列出兩個項目 - 我的猜測是,如果你使用Backbone開始,你可能會拉通過AJAX從服務器獲取項目列表,然後使用該列表填充表格。在這種情況下,通常你實際上是在ItemView類中創建每一行的DOM:

var ItemView = Backbone.View.extend({ 
    // there are many different ways to do this, here's one 
    tagName: 'tr', 
    className: 'item-row', 
    // make an Underscore template for the inner HTML 
    template: _.template(
    '<td class="price"><%= price %></td>' + 
     '<td><input type="text" class="quantity" value="<%= quantity %>" /></td>' 
), 
    render: function(){ 
    // this.el is already set to a tr.item-row DOM element 
    $(this.el).html(
     // fill in the template with model attributes 
     this.template(this.model.toJSON()) 
    ); 
    // allows chaining 
    return this; 
    } 
    // ... now your events and handler as written 
}); 

這給你一個ItemView其中,渲染時,有要插入可一旦你撥打.render()渲染元素。根據您的設置,您可能立即在initialize()函數中調用this.render(),或者您可能異步獲取更多數據,然後在回調中調用render()。無論哪種方式,你有一個視圖實例綁定到一個模型。要管理多個模型,我可能有另一個View類來保存收藏,這將是負責實例孩子ItemView實例:在你的代碼的主體

var ItemsView = Backbone.View.extend({ 
    el: '#myTable', 
    render: function() { 
     var tableView = this; 
     // instantiate and render children 
     this.collection.each(function(item) { 
      var itemView = new ItemView({ model: item }); 
      $(tableView.el).append(itemView.render().el); 
     }); 
    } 
}); 

然後,所有你需要做的是通過採集到父視圖,並使其:

var tableView = new ItemsView({ collection: totals }); 

還有很多更在這裏補充,大部分處理異步讀取,渲染和刷新數據從服務器,但希望這給你一個基本思路的方法。然而,我應該再次強調,這只是一種做事情的方式 - 例如,您可以僅使用類構建相同的應用程序,使其負責渲染所有項目本身。但是使用一個視圖來管理集合和子視圖來管理模型的方法可以很好地區分開來,並且有助於在應用程序變得更大時儘量減少複雜性。

+1

感謝您的詳細回覆。我會審查你的建議,並讓你知道結果如何。我之所以選擇硬編碼的DOM與ajaxing的原因是因爲其中一個已經存在了,我不想經歷一個簡化它的麻煩。但我認爲你正指着我朝着正確的方向前進。謝謝! – vinhboy