Backbone.js链接模型和VIew

时间:2011-10-07 15:59:14

标签: html 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中的这些字段?或者我应该在集合中更新它们吗?

如果有人有任何其他提示,我很乐意听到。这是我第一次使用骨干网,所以我只想要尽可能多的信息。谢谢!

1 个答案:

答案 0 :(得分:14)

与大多数Backbone问题一样,对此没有“正确”的答案 - 您需要找出最适合您的方法,这部分取决于您的应用程序可能会有多复杂

在你的设置中,对我来说似乎很奇怪的主要事情是你已经对你的表进行了硬编码以列出两个项目 - 我的猜测是,如果你开始使用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(),就会在渲染时让您想要插入的渲染元素可用。根据您的设置,您可以立即在this.render()函数中调用initialize(),或者您可以异步获取更多数据,然后在回调中调用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 });

这里还有很多内容,其中大部分内容涉及从服务器异步获取,呈现和刷新数据,但希望这能让您对该方法有一个基本的了解。但是,我应该再次强调,这只是一种做事方式 - 例如,您可以仅使用ItemsView类构建相同的应用程序,使其负责呈现所有项目本身。但是使用一个视图来管理集合以及子视图来管理模型的方法可以使事情保持良好的分离,并有助于在应用程序变大时最大限度地降低复杂性。