JavaScriptHow to

Essential JavaScript: the top five MVC frameworks

Essential JavaScript: the top five MVC frameworks

Picking the right MVC framework for your needs can be tricky. Jack Franklin sets out to make your decision easier by providing this guide to five of the most popular choices.

Advertisement

The massive growth in rich, JavaScript-heavy web applications has lead to a huge array of frameworks designed to help you build apps. There are so many that it can often be difficult to choose which best suits your needs, so in this article I'll discuss five of the most popular, and look at where each of their strengths lie.

You shouldn't base your decision entirely on this article - I encourage you to play further with a framework before committing - but I hope this sets you off in the right direction.

Most frameworks follow roughly what's known as an MVC pattern: model, views and controllers. Models deal with data, fetching it from databases and returning it. Views then display the data, and controllers link the models and views together. Of course, that's a very simplified explanation, but the idea in essence is to keep the presentation and the data completely separate, which brings huge benefits as your code starts to grow in complexity. If you've ever worked with a framework like CodeIgniter or Rails, the MVC approach will be familiar to you.

01. Backbone.js

We start with one of the most well known frameworks, Backbone.js. With Backbone, your data is represented in Models. Models can then be contained within Collections which are a collection of model instances. Views also offer more than just templates for displaying data, they also deal with binding events. One of my favourite things about Backbone is the hugely extensive documentation, which makes it much easier to really get to grips with the framework.

An important note is that there is no such thing as a typical controller in Backbone. The job of the controller tends to more be done partially by Views - they contain UI logic along with represting data, as we'll see shortly, and the Backbone Router, which maps URLs to functions. Collections are described on the Backbone site as "A group of models on the client-side, with sorting/filtering/aggregation logic".

You typically define methods to filter your data on collections. For example, the example Backbone todo app defines methods to filter just the todos marked "done":

    var TodoList = Backbone.Collection.extend({
          ...
          done: function() {
            return this.filter(function(todo){ return todo.get('done'); });
          }
          ...
      });

The above todo app is well worth examining if you're new to Backbone - it's fully commented and very helpful when it comes to deciding how best to lay out your application. One of the issues (if you could call it that) with Backbone is that there are a lot of different ways to achieve the same end goal. Don't get confused if online tutorials do things slightly differently.

 Backbone.js

In my opinion, Backbone is great for small, one page applications, and that's how I tend to use it. However there are plenty of people who have built impressive, vast applications with it, including USA Today and the New Rdio. Plenty more are cited on the Backbone site. I encourage you to give it a try and see how you find it.

02. Ember.js

Second is Ember.js. Whilst Backbone is fairly low level, with a lot of code that you need to write yourself, such as code to update the view when model data changes, Ember does a lot of that work for you. It's more opinionated because it tries to do a lot more for you, but that also leads to you having to write less boilerplate code.

Ember's main features are its data binding; obejcts in Ember can bind properties to each other, so when a property changes in one object, the other is kept in sync. Another is the ability to define functions on an object that you can then treat as properties. Hence, if a model has a first and last name, you could create a function to define a person's fullname, and have it treated as if the model has a fullname property. For example, here's how you might define such a property:

    fullName: function() {
        var firstName = this.get('firstName');
        var lastName = this.get('lastName');
        return firstName + ' ' + lastName;
      }.property('firstName', 'lastName')

You can then reference fullName as if it was a property throughout your code and in your views. For example, with the above property defined, your view might look something like:

    <p>Hello, <b>{{fullName}}</b>!</p>

And this would automatically update when the value changed. A combination of data binding and computed properties is very powerful.

Coming from a Backbone perspective, the feature most likely to draw you in is that Ember automatically updates its views when data changes - saving you a lot of work. This comparison post between the two sums it up quite nicely: "Backbone is more explicit and less magical". Depending on your perspective, that can be a good or a bad thing. Some prefer Backbone because it keeps things simple, and lets you do everything how you want, whereas Ember does much more for you. A framework that does more for you means you relinquish some of the control, but gain time in not having to write code to handle a lot of the mundane functionality.

 Ember

Ember also has more traditional controllers. Views (usually written in Handlebars) provide ways of attaching certain buttons or links to Ember controller actions. Of course, controllers don't need to deal with updating content, but can house methods to deal with just about everything else. This is where most of your methods will go that deal with the data. In a todo app, for example, you might write methods that return just the completed todos, or the methods that save another todo item.

03. Angular.js

Next up is Google's offering, the relatively new AngularJS. Angular takes a slightly different approach by doing data binding directly in your HTML. It also uses just plain JavaScript for its controllers, meaning there's no need to extend other objects as you have to do in other frameworks. The data binding means data in views is automatically updated when the data changes, but also Angular makes it effortless to bind forms to models, meaning a lot of the code you typically write to link a form to creating a new instance of a model is not needed. Its data binding is bi-directional. For example, here's the HTML for a form for a todo app (taken from the Angular documentation):

    <form ng-submit="addTodo()">
            <input type="text" ng-model="todoText"  size="30"
                   placeholder="add new todo here">
            <input class="btn-primary" type="submit" value="add">
          </form>

Notice the use of ng-* attributes within the HTML, which is where the majority of the magic lies. The ng-submit attribute will capture the form submit event and pass it to the addTodo method, which is a method on the todo controller. By declaring the ng-model attribute on the text field, you can easily get at the value without having to reference the field's DOM element and grab the value.

 Angular.js

By moving a lot of the binding directly into the HTML, Angular leaves you with much leaner controllers and less JavaScript to write. It might take a while to get your head around, but this approach is really powerful. The Angular home page contains multiple sample apps and videos of those apps being built, so if this interests you I highly recommend you check them out.

04. Knockout.js

Knockout.js is an MVVM (Model-View-View Model) framework written in pure JavaScript. MVVM frameworks are split into three parts. Firstly, there are models, which are exactly what you'd expect. Typically these sync data with a server.

You then have view-models, which are pure JavaScript and are a code representation of your data along with exposing methods for manipulating the data - these are as close to controllers as an MVVM framework comes. The bulk of your logic goes into these. Finally there are views, which display the information. These are written in pure HTML with bindings inserted as attributes (similarly to how Angular JS does it), which Knockout then uses to update views with the data. Knockout does this for you.

As an example, to display the firstName property of a model instance, my view would contain:

 <p>First name: <strong data-bind="text: firstName"></strong></p>

You then activate Knockout by applying the bindings. You pass this function an instance of your view model, which defines the value of properties. For example, something like:

       function AppViewModel() {
        this.firstName = "Bert";
      };

You can then activate the bindings like so:

ko.applyBindings(new ViewModel());

 Knockout.js

And you'll see the strong tag show "Bert". This code was taken from the interactive KO tutorial, which is the best place to start if you're interested in learning more.

05. Batman.js

Finally, I wanted to pick something different to all of the above and went with Batman.js, and not only because of the name. Batman is written in CoffeeScript. It can be used with JavaScript or CoffeeScript, but your code will look much cleaner in CoffeeScript as Batman makes use of CoffeeScript's classes heavily.

I'd only recommend Batman if you are happy to write CoffeeScript. With Batman you create an instance of Batman.App, which acts as a wrapper around your application. Then, you create controllers and models within this App class. App classes are very straight forward:

     class Todo extends Batman.App
        @global yes
        @root 'todos#index'

The first line sets it to global, so it's added as a property on the global object. The second line will look familiar to those with Rails experience. This sets the application's root path to be the index action on the controller. Controllers and methods get added as properties on this class. Batman also uses data-bindings in the HTML. For exmaple, to output a list item for each item in a product model, it's as easy as:

    <li data-foreach-product="Product.all">
        <a data-route="product" data-bind="product.name">name will go here</a>
      </li>

Batman is a great choice if you're a fan of CoffeeScript. It's quick to pull simple apps together and is also probably the framework to stay closest to what I would consider a typical MVC pattern.

 Batman.js

Nick Small, Batman.js' creator, has a great presentation on how and why you should use Batman.js. It unfortunately doesn't seem to be as popular as the other frameworks out there which I think is a shame, as the amount you can do in such little code is fantastic.

06. Conclusion

It was very hard in this article to pick out five frameworks and try to give them a fair overview in a limited number of words. The last four are pretty similar, with Backbone probably the odd one out. It does leave you with more work to do, and doesn't provide bindings, a key feature of the others, but if you want full control over everything, it's a good one to look into.

The key advice I would give is to look at apps written in these libraries and try to write your own small apps before commiting to one. Each has subtle differences which will either suit you or not, and it's good to find those out sooner rather than later.

Of course, there are plenty more than these five, and the Todo MVC project is a great place to start if you'd like to explore other options. That site has a huge collection of applications written in a great variety of frameworks, including all the ones mentioned in this article. You can find the repository of these applications on Github.

Thanks to Addy Osmani for his peer review of this article

Jack Franklin is a 20 year old developer living in London, UK. He runs a JavaScript blog at javascriptplayground.com and also writes PHP, Ruby and other languages. He tweets as @Jack_Franklin.

Liked this? Read these!

Subscription offer

Log in to Creative Bloq with your preferred social network to comment

OR

Log in with your Creative Bloq account

site stat collection