Let me start off by saying Backbone is great. Really great. In fact I don’t know what I did before it. Kind of like that duh moment when you first started using jQuery to interact with the DOM.

Having said that, there are quite a few tasks I perform over and over with Backbone that can get somewhat repetitive. This is why we are going to extend a Backbone View to add some extra functionality to it.

Extending a view

Extending a Backbone view is pretty simple. In our example below we are going to create a new object called a “Backbone.Scene”. Our scene object is going to inherit all of the methods and properties of a regular view but also let us add some functionality.

First we extend a Backbone.View

Backbone.Scene = Backbone.View.extend({});

Next, we extend the Backbone.Scene prototype to add properties and methods relating to our Backbone.Scene. And that’s all there is to it.

_.extend(Backbone.Scene.prototype, {
    // Add scene logic here.
});

You may be asking well this is great and all, however what kind of extra functionality could I add to a Backbone.View?

Adding an “elements” hash

Spine has this concept of an “elements” hash which is nice when you want to create properties on an instance of a view that relate to specific elements within your $el object. Confusing? Just read on.

Say you have this markup for a scene named calendar.

<div id="calender-view">
  <div class="calender-button">
    <button id="calendar-picker" class="circle-button pictos-button">\</button>
  </div>
  <div class="calendar-page">
	<div class="calendar-page-content clearfix"></div>
  </div>
</div>

You might have multiple elements in your markup that would be nice to have as properties on your scene instance. In this particular example it would be nice to have a reference to the button and the calendar-page-content area. We would like to be able to declare the following “elements” with a property name and jQuery/Zepto selector.

var BookScene = Backbone.Scene.extend({
  elements: {
    'calendarPicker': '#calendar-picker',
    'calendarPageContent': '.calendar-page-content'
  },

  initialize: function() {
    this.applyElements();
    this.calendarPicker.on('click', this.pickerClicked);
  },

  pickerClicked: function( e ) {
    // Handle calendar clicked.  
  }
});

So, this looks pretty good. As you can see calendarPicker is now a property on our scene instance. However, we have this magical function “applyElements” that is not in our extended scene. So where is applyElements? It is on our Backbone.Scene prototype.

Backbone.Scene revisited

We can update our Backbone.Scene from above to include a new method called applyElements(). This will now be available to any extended Backbone.Scene instance. applyElements() is pretty simple. It will loop through each element and set a property that points to a particular cached selector.

_.extend(Backbone.Scene.prototype, {
  applyElements: function() {
    if ( this.elements ) {
      _.each(this.elements, function( item, key ) {
        this[key] = this.$el.find(item);
      }, this);
    }
  }
});

What else?

Creating the concept of elements on a view is just one small example of extending the functionality of a Backbone.View. Another possible extension could include fetching, compiling and rendering underscore templates.

A Full Backbone.Scene Example