Link Model Backbone.js and VIew

I have a table like this

<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> 

What I am manipulating with this js code of the main page

 <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> 

My questions.

1) As long as I can manage one line, that's fine. But then I want to control the second line. Am I just instantiating another instance of ItemView ? Or can I use one instance of ItemView to manage multiple Models ? Or better yet, with Collection

2) I use Collection to manage subtotals and nationality. Create a separate view to manage these fields in the DOM? Or should I just update them inside the collection?

If anyone has any other advice, I would love to hear that. This is my first time with the spine, so I just want as much information as possible. Thanks!

+4
source share
1 answer

As with most basic questions, there is no β€œright” answer to this question - you will need to find the approach that is best for you, which partly depends on how complex your application can be.

The main thing that seems strange to me in your setup is that you hardcoded your table to list the two elements - I assume that if you use Backbone to start, you will probably list the elements from the server via AJAX, and then populate the table with this list. In this case, you usually create a DOM for each row of the ItemView class:

 var ItemView = Backbone.View.extend({ // there are many different ways to do this, here 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 }); 

This gives you an ItemView that, when rendered, has the rendered item that you want to insert after calling .render() . Depending on your setup, you can immediately call this.render() in the initialize() function, or you can get additional data asynchronously, and then call render() in the callback. In any case, you have one instance of the view attached to one model. To manage multiple models, I can have another view class that will contain a collection that will be responsible for instances of child instances of 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); }); } }); 

Then, in the main part of your code, all you need to do is pass the collection to the parent view and make it:

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

There is a lot to add, most of them are connected with asynchronous extraction, rendering and updating of data from the server, but, hopefully, this gives you a basic idea of ​​the approach. Again, however, I must emphasize that this is just one way to do something - you could, for example, build the same application with only the ItemsView class, which would make it responsible for rendering all the elements. But the approach of using a single view to manage the collection and child views to manage the models perfectly separates things and helps minimize complexity as your application grows.

+14
source

All Articles