Backbone.js链接模型和VIew

vin*_*boy 4 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>
Run Code Online (Sandbox Code Playgroud)

我正在使用这个主干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>
Run Code Online (Sandbox Code Playgroud)

我的问题是.

1)到目前为止,我可以管理一行,这很好.但后来我想管理第二行.我只是实例化另一个实例ItemView吗?或者我可以使用一个ItemView实例来管理多个Models?或者更好的是,随着Collection

2)我正在使用它Collection来管理小计和子量.我是否创建了一个单独的视图来管理DOM中的这些字段?或者我应该在集合中更新它们?

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

nra*_*itz 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
});
Run Code Online (Sandbox Code Playgroud)

这将为您提供一个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);
        });
    }
});
Run Code Online (Sandbox Code Playgroud)

然后在代码的主体中,您需要做的就是将集合传递给父视图,然后呈现它:

var tableView = new ItemsView({ collection: totals });
Run Code Online (Sandbox Code Playgroud)

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