Updating single view on change of a model in backbone The setup of Backbone:

1 Collection,
3 Models,
1 View for the collection, 
1 View per Model.

HTML:

&lt;div id="showit"&gt;&lt;/div&gt;


Template:

&lt;script id="item-template" type="text/x-handlebars-template"&gt;
    &lt;a class="item" href="#"&gt;{{book.name}}&lt;/a&gt;
    &lt;br/&gt;
    &lt;span&gt;Liked :{{book.likes}}&lt;/span&gt;&lt;br/&gt;
&lt;/script&gt; 


Backbone JS:

Book    =   Backbone.Model.extend({
            defaults:{
                name    :   "No Name",
                author  :   "No Name",
                likes   :   0
            }

BookListView    =   Backbone.View.extend({
                        collection  :   BookList,
                        initialize  :   function(collection){
                            this.collection = collection;
                            this.render();
                        },
                        render      :   function(){
                            this.collection.each(function(model){
                            var pustakView = new BookView({model: model});
                            pustakView.render();
                            });                                
                        }                              
});

BookView    =   Backbone.View.extend({
    model       : Book,                
    initialize  : function(){},       
    events      : {"click a.item": "clicked"},
    template    : Handlebars.compile($('#item-template').html()),

    clicked     : function(e){
                    e.preventDefault();
                    var likes_count =    this.model.get("likes");
                    this.model.set({likes:++likes_count});
                    this.renderOne();
    },

    renderOne   : function(){
                    var output=this.template({'book':this.model.toJSON()});
                    $(this.el).html(output);                    
    },
    render      : function(){
                    var output = this.template({'book':this.model.toJSON()});
                    $(this.el).append(output);
                    $('#showit').append($(this.el));
     }  
});  

var book1   =   new Book({name:'Awesome Book1',author:"John",likes:10});
var book2   =   new Book({name:'Awesome Book2',author:"Dave",likes:20});
var book3   =   new Book({name:'Awesome Book3',author:"Bill",likes:30});

BookList    =   Backbone.Collection.extend({model:Book});
var myBookCollection    =   new BookList([book1,book2,book3]);
myBookList  =   new BookListView(myBookCollection);


So here is a snippet of what it generates on page load:

&lt;div id="showit"&gt;
    &lt;div&gt;
       &lt;a class="item" href="#"&gt;Awesome Book1&lt;/a&gt;&lt;br&gt;
       &lt;span&gt;Liked:10&lt;/span&gt;&lt;br&gt;
    &lt;/div&gt;
...
...
&lt;/div&gt;


I am a newbie into world of backbone and trying to implement the basics to apply it into my site. I have referred this site for the above implementation. (Well, not exactly as I have customized it for my needs).

The feature I have been trying to implement is that multiple models with same template will load in 1 Collection, clicking on any element in the rendered view of that model has to give me access to that model so that I can re-render the view of the clicked model only.

The above example does the same where in clicking a hyperlink updates the counter called 'likes' and updates the corresponding model view only. As it can be noticed I have not specified an 'el' attribute for the view of each model and so it will be a 'div'.

My Question is whether this method is an efficient method of updating individual views (when model attributes change due to events) or are there any better methods than this? Also I am not sure if having a view for each loaded model will not cause any memory issues (asuuming I have an infinite scroll implemented which keeps on loading the list of Books)

If the above implementation is good enough, I hope it can help other backbone newbies to get up and running with re-rendering model view when model attributes change.
First of all, Backbone views already have a cached version of $(this.el) in this.$el so you should use this.$el instead of $(this.el).

I find that things work better when views only touch their own el and leave it up to someone else to put that el into the DOM. In your case, that would mean that you shouldn't do this:

$('#showit').append($(this.el));


in the sub-view, it would be better to say:

render: function() {
    var output = this.template({'book':this.model.toJSON()});
    this.$el.html(output);
    return this; // &lt;----------------- this is common behavior, you'll see why in a moment
}


and then in the parent view, you say this:

el: '#showit',
render: function() {
    this.collection.each(function(model) {
        var pustakView = new BookView({model: model});
        this.$el.append(pustakView.render().el);
    }, this);
    return this;
}


The parent adds the child using the child's new return value from render:

this.$el.append(pustakView.render().el);
// ---------------------------------^^


Also note the second argument to this.collection.each to make this inside the iterator function the parent view.

Now we don't need renderOne in BookView at all, you can bind render to the appropriate event. You can also leave the re-rendering up to Backbone. When you say this:

this.model.set({likes: ++likes_count});


you will trigger a 'change' event on this.model. If you bind to that in initialize:

initialize: function() {
    this.listenTo(this.model, 'change', this.render);
}


then Backbone will call render for you when the model changes.

Back to BookListView. A view's initialize will copy the collection property out of its options just like it will copy model:


  constructor / initialize new View([options])
  
  There are several special options that, if passed, will be attached directly to the view: model, collection, el, id, className, tagName, attributes and events.


so your BookListView should look more like this:

var BookListView = Backbone.View.extend({
    initialize: function() {
        this.render();
    },
    //...


and you should instantiate it like this:

var myBookList = new BookListView({ collection: myBookCollection });


Notice that I have removed collection: ... from the view declaration. The collection and model properties should be instances and they should be bound per-view-instance so you almost never want collection or model to appear when defining a view, you only want to see those in the view's argument list when you instantiate a view.

Furthermore, I notice that you're not using var to declare your variables. That means that you are creating accidental globals all over the place and that's never a good idea. Always use var to declare variables so that you can control the scope.