Introduction

 

Almost every developer who has worked with server-side applications, whether in Ruby, Java, C#, PHP, Python or any other modern language, has already experienced the MVC paradigm to some extent. Even if you started your coding adventures mixing PHP together with HTML, the natural progression is to migrate to a more structured approach, separating concerns between the different parts of the application. In case you are not familiar yet with the term, MVC stands for Model-View-Controller and, in a nutshell, means that the code that handles the user interface (the view) is not mixed with code to access the database (model); instead, these are separated into distinct units, with a "controller" that links them via a well-defined interface. Have a look at the Wikipedia entry for more in-depth information. This results in applications that are easier to maintain and extend (and more fun to write).

 

 

What is Javascript MVC and why you should care

 

Javascript code, in general, did not enjoy the same amount of attention to these best practices for a long time. While there is a plethora of frameworks to choose from in other languages, it is only recently that robust Javascript MVC frameworks have appeared which bring some much-needed structure to browser applications. This "Javascript Renaissance" coincides, and not by accident, with the need to bring more and more functionality to the client (browser) side of applications, first with AJAX and with increasing frequency, with entire, complex applications being written in Javascript that operate entirely in the browser and use the server merely as a data source.

 

Javascript MVC frameworks are, in simple terms, code libraries that help you build applications in a more structured way. Additionally, some frameworks also provide utilities to work with REST APIs, templating and other functionality.

 

The main reason to adopt an MVC framework is that non-trivial applications in Javascript get more cumbersome to write as they grow and a framework will help you keep the different pieces manageable. Adding more features to your application should not become exponentially hard over time, a framework will help with that.

 

One reason to take Javascript MVC seriously is that, with the introduction of RhoMobile 4, it is now possible to access every feature directly from Javascript, no Ruby involved. Scanning barcodes? check. Database access? check. Network communication? check. Awesomeness? double check.

 

 

The Javascript MVC landscape

 

 

If in the past there was not much in the way of Javascript MVC frameworks to choose from, the problem today is exactly the opposite: the number of options has exploded into an unbelievable variety, each offering a different flavor and opinion on how applications should be built. It is out of the scope of a single article to evaluate all or even a majority of them (it would take a whole book to do so, and it would be outdated before it was published). Fortunately, there is a fantastic resource at http://todomvc.com/ where you can see one application (a to-do list) developed in multiple frameworks so that you can get a feel for the style and idioms of each. By looking at how each framework is used in a real, if small, application, you can make an informed decision about which one(s) to evaluate in more depth and eventually adopt.

 

Backbone.js

 

Backbone.js is a favorite framework for single-page applications due to its ease of use. It provides a set of conventions and building blocks to base your application on, but does not dictate the use of any particular library for building HTML views. You are free to use the included Underscore.js templating functions, mustache, handlebars or any other templating library. Once you start to develop your first Backbone.js application, you will quickly appreciate the difference between using a structured approach and the free-for-all spaghetti code that can result in plain jQuery applications once they reach a certain size.

 

There are only a few concepts Backbone.js that you must learn about in order to start being productive:

 

  • Models
  • Views
  • Router

 

Models

 

Put simply, models hold data. You create one model class per entity in your application (Product, Customer, etc) and then get and set properties on instances of that class.

 

Example:

 

var Product = Backbone.Model.extend({
  defaults: {
  sku: '',
  available: true
  },


  toggleAvailability: function() {
  this.set("available", !this.get("available"));
  }
});

 

Views

 

Views are used to render HTML. Instead of building your HTML by concatenating strings in code, a templating library will help you create HTML with a readable syntax that facilitates maintenance and change. Backbone.js does not force you to use any particular templating library, and if you do not have any preference yet, have a look at the included Underscore.js templating functions. They are very easy to get started with and will be just enough for many applications.

 

The easiest way to keep your templates manageable is to have them in an HTML file instead of a Javascript string, as that frees you from the burden of quoting, escaping special characters, etc. You can embed a template inside a <script> tag as long as you set the type attribute so that the browser does not attempt to run it as Javascript code:

 

<script id="productlist_template" type="text/template">
    <ul>
        <% _.each(products, function(product) { %>
            <li><%- product.get("sku") %> | <%- product.get("sku") %></li>
        <% }); %>
    </ul>
</script>

 

Later, in your Javascript code you can reference the template by ID and get its contents with .html():

 

var ProductListView = Backbone.View.extend({
  // this is the element on the page that this view will live in
    el: "#content",
    events: {
    //  'event    selector'       : 'method'
        'click button.create_product' : 'create_product'
    },
    initialize: function() {
        // compile template into a function and store it for future use
        this.template = _.template($("#productlist_template").html());
    },
    render: function(products) {
        // call the template to render a list of products
        var template_contents = this.template({ products : products || [] });
        $(this.el).html(template_contents); // write the template to our assigned element
    },
    create_product: function() {
    // create a product here
    }
});

 

Router

 

The router is in charge of mapping changes in the URL to actions in your code and, generally, rendering a different view. Whenever the fragment (the part after the #) changes, the router will fire an event that you can listen and react to as required.

 

 

var Router = Backbone.Router.extend({
    routes: {
        // fragment : 'method'
        ''          : 'home',
        'new'       : 'editProduct',
        // routes can also automatically interpret parts of the URL as parameters
        'edit/:id'  : 'editProduct'
    },
});

var router = new Router();


router.on("route:home", function() {
    // render home view
});

router.on("route:editProduct", function(productId) {
    // render "edit product" view, possibly with a particular productId
});

// Start listening to changes in the URL
Backbone.history.start();

 

RhoMobile 4 and Backbone.js - a match made in heaven

 

That is all you need to start building MVC applications in Javascript with Backbone.js, although there are of course some features we have not covered here. Now that you have gotten a taste of it, you can see a more comprehensive example on how to build a small CRUD application, including database access with Rhom. Backbone.js is officially supported in RhoMobile 4 and there is an integration library called RhoTendon (also discussed in the example) that helps you link Backbone.js models with Rhom for ultra-rapid development. Add to the mix the new unified access to all RhoMobile APIs in Javascript and you can start building 100% Javascript mobile enterprise apps today.