Search icon CANCEL
Subscription
0
Cart icon
Your Cart (0 item)
Close icon
You have no products in your basket yet
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Conferences
Free Learning
Arrow right icon
Arrow up icon
GO TO TOP
Backbone.js Patterns and Best Practices

You're reading from   Backbone.js Patterns and Best Practices Improve your Backbone.js skills with this step-by-step guide to patterns and best practice. It will help you reduce boilerplate in your code and provide plenty of open source plugin solutions to common problems along the way.

Arrow left icon
Product type Paperback
Published in Jan 2014
Publisher Packt
ISBN-13 9781783283576
Length 174 pages
Edition Edition
Languages
Arrow right icon
Author (1):
Arrow left icon
Swarnendu De Swarnendu De
Author Profile Icon Swarnendu De
Swarnendu De
Arrow right icon
View More author details
Toc

Table of Contents (19) Chapters Close

Backbone.js Patterns and Best Practices
Credits
About the Author
Acknowledgments
About the Reviewers
www.PacktPub.com
Preface
1. Reducing Boilerplate with Plugin Development FREE CHAPTER 2. Working with Views 3. Working with Models 4. Working with Collections 5. Routing Best Practices and Subrouting 6. Working with Events, Sync, and Storage 7. Organizing Backbone Applications – Structure, Optimize, and Deploy 8. Unit Test, Stub, Spy, and Mock Your App Books, Tutorials, and References Precompiling Templates on the Server Side
Organizing Templates with AMD and Require.js Index

Re-using code with extensions


Backbone is quite a small library in comparison with other libraries. Any complex application can be structured and developed with Backbone, but the framework itself doesn't come with prebuilt widgets or reusable UI components. In this section, we will talk about some Backbone and JavaScript techniques that will help you build a reusable interface library.

For simple and small applications, code reusability doesn't always seem much of a necessity. But as you proceed to create an application with multiple views, models, and collections, you find that a certain portion of your code gets repeated several times. Creating reusable extensions and plugins in such cases improves the performance of the application by enhancing modularity and reducing the code size. Let's create a simple Backbone view to understand how we can create an extension, shown in the following code snippet:

var User = Backbone.Model.extend({
  defaults: {
    name: 'John Doe'
  }
});

var UserItemView = Backbone.View.extend({
  template: '<span><%= name %></span>',
  render: function () {
    var tpl = _.template(this.template),
      html = tpl(this.model.toJSON());

    this.$el.html(html);
    return this;
  }
});

// Create a view instance passing a new model instance
var userItem = new UserItemView({
  model: new User
});

$(document.body).append(userItem.render().el);

The view named UserItemView is a simple Backbone view where we want to display our model data inside a template and append this view element to the DOM. This is a fundamental functionality of Backbone where the primary requirement is to display a model's data as a view. If we have another similar view with a model, and this has the same functionality, the render() function will also be identical. That said, won't it be beneficial if we move the common code to a base class and extend that class to inherit the functionality? The answer is yes. Let's see how we can do that in the example in the following section.

Creating a base class

We create a BaseView class where common functionality such as the render() method is added. Then all other view classes can extend from this base class, and eventually inherit the rendering functionality. The following is the BaseView class with minimal rendering functionality:

// Parent view which has the render function
var BaseView = Backbone.View.extend({
  render: function () {
    var tpl = _.template(this.template),
      data = (this.model) ? this.model.toJSON() : {},
      html = tpl(data);

    this.$el.html(html);
    return this;
  }
});

Now, UserItemView will look much better. We will extend the BaseView class and will provide only the template as follows:

// A simpler view class
var UserItemView = BaseView.extend({
  template: '<span><%= name %></span>'
});

Tip

Downloading the example code

You can download the example code files for all Packt books you have purchased from your account at http://www.packtpub.com. If you purchased this book elsewhere, you can visit http://www.packtpub.com/support and register to have the files e-mailed directly to you.

If you wish to add some extra functionality such as calling another function in your view's render() method, you can override the render method of the base class. Check the following example:

var UserItemView = BaseView.extend({
  tagName: 'div',
  template: '<span><%= name %></span>',
  render: function () {
    // Call the parent view's render function
    BaseView.prototype.render.apply(this, arguments);

    // Add your code here
    this.anotherFn();
    return this;
  },

  anotherFn: function () {}
});

There are a number of functionalities that you can move to your base class depending on your requirements. For example, in a non-trivial application, we often need to replace a view with another, destroy the old view by removing it from DOM, and clean up other dependencies. So, we can add a close() method to BaseView (as shown in the following code) that can take care of every view removal mechanism.

var BaseView = Backbone.View.extend({
  render: function () {
    var tpl = _.template(this.template),
      data = (this.model) ? this.model.toJSON() : {},
      html = tpl(data);

    this.$el.html(html);
    return this;
  },

  close: function () {
    // Extra stuff goes here

    // Remove the view
    this.remove();
  }
});
// This is not production-ready code, but it clearly gives you the concept of using custom widgets to reduce boilerplate in your code. It will not always be necessary to extend a Backbone class to create a plugin.

Developing plugins without extending base classes

Sometimes we find that creating a constructor function and adding methods to its prototype can be a better choice than extending the Backbone base classes. For example, in the Pagination plugin in the following code, instead of creating a PaginationCollection class by extending Backbone.Collection, we will prefer to go for a simpler class—a constructor function that accepts two arguments: a collection and the number of the items to be shown in a page.

// Pagination constructor function
var Pagination = function (collection, noOfItemsInPage) {
  if (!collection) {
    throw "No collection is passed";
  }
  this.currentPage = 1;
  this.noOfItemsInPage = noOfItemsInPage || 10;
  this.collection = collection;
}

// Use Underscore's extend method to add properties to your plugin
_.extend(Pagination.prototype, {
  nextPage: function () {},
  prevPage: function () {}
});

var User = Backbone.Model.extend({
  defaults: {
    name: 'John Doe'
  }
});

var Users = Backbone.Collection.extend({
  model: User
});

var paging1 = new Pagination(10, new Users());
var paging2 = new Pagination(20, new Users());

We didn't add the actual functionality, but just showed a skeleton of how the Pagination class may look. The benefit can be observed when you already have a collection and you want to implement pagination without extending a parent collection class. We added the member variables in constructor function so that individual instances of this class can have their own set of variables. On the other hand, the methods are added to the prototype of the class so that they are shared by all instances of the class.

This mechanism can be useful when you need a custom plugin that is not a type of Backbone view, model, or collection.

You have been reading a chapter from
Backbone.js Patterns and Best Practices
Published in: Jan 2014
Publisher: Packt
ISBN-13: 9781783283576
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at $19.99/month. Cancel anytime
Banner background image