Skip to content

Instantly share code, notes, and snippets.

@OmeGak
Last active December 24, 2015 23:39
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save OmeGak/6882422 to your computer and use it in GitHub Desktop.
Save OmeGak/6882422 to your computer and use it in GitHub Desktop.

#Indico client-side MVC It's time to go full MVC in Indico!

Why MVC?

We all want our architecture to be simple, yet beautiful.

When developing applications using just jQuery, the piece missing is a way to structure and organize your code. It’s very easy to create a JavaScript app that ends up a tangled mess of jQuery selectors and callbacks, all desperately trying to keep data in sync between the HTML for your UI, the logic in your JavaScript, and calls to your API for data.

A number of modern JavaScript frameworks provide developers an easy path to organizing their code using variations of a pattern known as MVC (Model-View-Controller). MVC separates the concerns in an application into three parts:

  • Models represent the domain-specific knowledge and data in an application.
  • Views typically constitute the user interface in an application. They observe Models, but don’t directly communicate with them.
  • Controllers handle input (e.g., clicks, user actions) and update Models.

Thus, in an MVC application, user input is acted upon by Controllers which update Models. Views observe Models and update the user interface when changes occur. Backbone merges the responsibility of the Controller into the View, therefore it's called MV*.

But where to use it?

  • For complex user interfaces
  • When trying to reduce the number of HTTP requests

Current state in Indico

Indico's Registration Form serves as a prototype of MVC implemented with Backbone. The current task is to refactor the code and interface to comply with our standards.

Some tasks:

  • Templating engine: UnderscoreJS mini templates
    • It simply embeds JS into the HTML
    • Migrating to Nunjucks (port of Jinja for JS)
  • Logic is found in templates:
    • Moving it to Views (quite hacky)
    • Would require some rethinking in how the models hold the information coming from the back-end

Comparative: Backbone vs Angular.js

Let's compare Backbone because it's the current prototype and Angular because it seems the most promising framework.

Features

Things we should be looking for in a MVC framework:

  • Observables: Objects that can be observed for changes.
  • Routing: Pushing changes to the browser url hash and listening for changes to act accordingly.
  • View bindings: Using observable objects in views, having the views automatically refresh when the observable object change.
  • Two way bindings: Having the view push changes to the observable object automatically, for example a form input.
  • Partial views: Views that include other views.
  • Filtered list views: Having views that display objects filtered by a certain criteria.

Clear winner:

  • Angular have all of these by default.
  • Backbone is able to do most of them with a lot of manual code or plugins.

Flexibility

  • Angular is very opinionated and you must find how to do things its way. Avoids taking decisions but can be more difficult for specific cases.
  • Backbone is more flexible as it is less opinionated. You are required to make a lot of decisions.

Learning curve

  • Angular is easy at the beginning. After learning the basic stuff the curve gets steeper. Has lots of peculiarities.
  • Backbone is easy to learn but requires knowing 'best practices' to make good design decisions. Usually, it needs other libraries (Marionette) to get things done. This increase the difficulty.

Productivity

  • Angular is the winner here thanks to all built-in features.
  • Backbone requires a lot of boilerplate code or libraries.

Ecosystem

  • Angular is starting to get interesting with Angular UI.
  • Backbone has tons of plug-ins.

Size

  • Angular: 80k
  • Backbone: 18k

However, Backbone requires Underscore and probably a template engine (Nunjucks).

  • Backbone: 18k + 14k + 19k = 51k

Unobtrusive vs declarative

There is bit of controversy regarding this point. Unobtrusive principles say that the HTML should not mix functionality and presentation. However, declarative principles applied on web development aim for freeing the developer from low level DOM manipulation tasks as it describes how the UI should change as your application state changes.

Some discussions to throw in more insight:

Code examples

Angular (doc)

<!doctype html>
<html ng-app>
  <head>
    <script src="http://code.angularjs.org/1.2.0-rc.2/angular.min.js"></script>
    <script src="script.js"></script>
  </head>
  <body>
    <div ng-controller="HelloCntl">
      Your name: <input type="text" ng-model="name"/>
      <hr/>
      Hello {{name || "World"}}!
    </div>
  </body>
</html>
function HelloCntl($scope) {
  $scope.name = 'World';
}

Backbone

<html>
<head>
  <title>Hello world using a Backbone.js view!</title>
</head>
<body>
  <div id="main">
  </div>
</body>
</html>
$(function(){

  //Backbone code - begin
  var HomeView = Backbone.View.extend({
    id: "hello-world-id",
    tagName: "div",
    className: "hello-world",
    template: null,

    initialize: function() {
      _.bindAll(this);
      this.template = _.template('<div>Hello <strong>world!</strong></div>');
    },

    render: function() {
      this.$el.html(this.template());
      return this;
    }
  });
  //Backbone code - end

  var test = new HomeView();
  $('#main').append(test.el);
  test.render();
})

Some opinions

AngularJS is way bigger, provides a much higher level of abstraction and is very opinionated on how you should develop your app. It's a complete solution, with testing environment and philosophy behind it... That means, building an app is super fast, but it doesn't have to fit everyone nor every app. -- Vojta

Backbone trumps ultimate flexibility over developer convenience. Suffers of a serious lack of features and developer productivity. There are lots of plug-ins to compensate for this, but then you will be learning Backbone and something else on top. Backbone can also be very tempting because of its big community and the ecosystem, but this advantage will disappear as the other frameworks become more popular. -- sporto

Other interesting articles:

Future of Web development

Web Components seems to be The Next Big Thing. It is a W3C draft for the time being, but it's supported by Google and Mozilla.

Google is working on Polymer, a preview-like library to give developers a way to play around with the upcoming features of of Web Components API.

Angular is already providing what Web Components is aiming for. As the Web Components API become standardized, their plan is to substitute its implementation for native calls in order to improve efficiency and provide retro-compatibility with old browsers via polyfills123. It will then be a sort of jQuery level of abstraction plus an opinionated framework and test environment.

Backbone seems to be left out of the picture if Web Components really is the next big thing, or at least I was not able to find any relevant information on their plan towards the new API.

Conclusions

The situation is the following:

  • The Registration Form will be the first component using MVC
  • It should serve as a guide for future implementations
  • Regardless of the technology used it must be a seamless implementation
  • It will probably require a major refactor of the current prototype

Since we should anyway invest quite some time improving the Registration Form, we might as well go for the most convenient framework for Indico in the long run, which may not be Backbone. Backbone is not so much a framework but a Library. It's lighter and more flexible, but it means that YOU have to write the code and take decisions. It can be empowered with Marionette, but it increases the size and increases the complexity of the solution.

The lack of flexibility of Angular may play against us in the beginning as we'll feel tempted to find workarounds with jQuery, but its opinionated approach and built-in functionalities will surely improve our efficiency and make the front-end less bug-prone. As for the cost of exit, it might be more difficult to go away from Angular, but I think that's only because we are assuming that the popular technologies in 4~5 years will still be based on jQuery and templating engines instead of declarative HTML.

References

  1. A Comparison of Angular, Backbone, CanJS and Ember
  2. Stackoverflow: AngularJS vs Backbone
  3. TodoMVC
  4. Backbone Fundamentals
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment