Here is the general list of requirements (in no particular order) that we considered for evaluating the frameworks -
- Separation of concerns between components (MVC/MVVM/MV - whatever)
- Ease of use - learning curve and productive development
- Data Binding ability
- Modularity - logical code organization
- Templating and possibility of fetching them on-demand remotely
- Ability to play nicely with other libraries (mainly jQuery)
- Extensibility (ease of adding custom functionality)
- Reusable components - Capability to create reusable components
- Maturity and size of the community
After initial research and PoCs, we shortlisted the following frameworks/libraries -
Backbone.js is a well-established and well-respected library in the JS community. It's very easy to learn and plays nicely with jQuery. It doesn't provide bindings functionality out of the box. It's minimal by design and is a library, not a framework. Depending upon one's perspective, this can be viewed as a pro or a con. On one hand, it gives you absolute freedom and control to structure your application the way you want. On the other, it might be viewed as too "bare bones" and might result in having to write quite some "boilerplate" code to make things work together.
For us, it was more of the latter and therefore we had to let it go reluctantly.
This, in my opinion, is one of the best libraries available in the JS webapps frameworks/libraries world at the moment.
- Almost no learning curve. Super-easy to learn and use. Amazing documentation, live examples and tutorials, I would say right amongst the best in opensource projects.
- Does bi-directional data binding in declarative manner. You need to use KO api such as ko.observable and ko.computed to setup observables in your ViewModel.
- Plays nicely with jQuery.
- Has DOM-based templating which, in my opinion, is the right approach for templating.
- Provides custom bindings and custom functions as means of extensibility and creating custom components.
- Mature library with number of releases under it's belt and active community behind it.
- It's a library absolutely focused around View Models and bindings. Doesn't offer much for separation of concerns.
- Doesn't have any opinions on the logical code organization. This responsibility is left to the developers.
- Doesn't provide routing/bookmarkability out of the box. You have to choose and integrate third-party library such as Sammy.js for this purpose.
Based on our PoCs, KnockoutJS turned out to be our second most favourite library.
I have mixed feelings about ember. We had high expectations due to the SproutCore legacy and wanted to like it but were let down due severe lack of documentation and examples. (This situation might have changed for better in last six months.) Also, it was quite in flux back then and there was a lot of confusion about readiness and state of migration (from SproutCore to Ember) for plugins such as StateManager and ember-data. Absence of mailing list didn't help either. On the templating front, while I'm aware that a lot of people really like handlebars.js, I tend to differ. DOM-based templating looks a lot cleaner solution to me and it also preserves the IDE (or a nice text editor such as Sublime Text 2, which arguably is the best editor around these days) benefits such as syntax highlighting and code completion. A bunch of handlebars templates wrapped in script tags in an HTML file simply doesn't offer that luxury. Probably a minor point but still important when dealing with large applications.
We still took it to the final showdown but couldn't complete the spike in the allotted time frame owing to the factors mentioned above and hence dropped it from our consideration.
Batman.js is quite an impressive looking new framework. It takes inspiration from RoR and strives to be "Rails" of the JS webapp frameworks world with pre-defined directory structure, generators, test server and even a optimized NodeJS based server in the making.
- Batman provides clean separation of concerns on the MVC lines. While the model and controllers extend from framework classes, Batman.Model and Batman.Controller, the views are pure HTML with declarative data-* bindings.
- Batman Model provides a very rich API very similar to Rails ActiveRecord with functionality such as validations and CRUD being inherited by model subclasses.
- The StorageAdapter approach is a very clever approach for model persistence with strategies like Batman.LocalStorage and Batman.RestStorage available out of the box.
- The controllers are singleton and that is something that struck me as odd. It's sort of throwback to Struts days :).
- The routing is provided out of the box.
- It plays nicely with jQuery.
That brings us to the last framework in our list. I had an eye on AngularJS even before it got the "by Google" tag that now adorns its web site and clearly remember not liking the "ng" xml namespace approach. But amends happened in the nick of time for us :).
- AngularJS provides a clean separation of concerns on MVC lines. The most remarkable thing about scopes (which roughly correspond to model) and controllers is that they are pure JS functions. Unlike ember, knockout and batman, you don't need to extend from any framework specific extension points. AngularJS views are pure HTML with custom data-* attributes that provide two way bindings.
- It provides excellent means of logical code organization in the form of modules. It provides way to abstract shared functionality and data into services. It brings the the Dependency Injection paradigm to JS.
- It has a moderate learning curve since it defines quite a few abstractions of its own. But once you wrap your head around them, you realize it's all very logical. Though it's also quite a young project, the documentation is excellent and the mailing list is very active.
- Angular templates are DOM-based and you can have partials - templates divided into manageable chunks specific to single functionality and loaded on demand.
- Angular Directives is an amazing way of creating new components, composing them to create composite components and wrapping third-party widgets and exposing them as Angular components.
- Provides nice AJAX abstraction in form of $http service and $resource service built on top of it that provides means to interact with RESTful server-side data sources.
- Angular plays nicely with jQuery. If you load jQuery before Angular, it uses that by default for DOM manipulation tasks.
- It has an excellent routing support in form of $routeProvider service. You can also define routes dynamically, for example, getting JSON response from REST service and define routes based on it.
- Testing has always been a challenging concern in UI development. But due to excellent logical code organization features like modules and services, controllers and scopes being pure JS functions and dependency injection, unit testing is one area where Angular really shines.
AngularJS very quickly became our favourite framework in our PoCs.
We selected KnockoutJS and AngularJS for our final showdown. We did spikes in both to implement similar functionality and arrive at result -
and the framework we selected is - AngularJS.
We have been developing in AngularJS since. The results have been outstanding and we are very happy with our choice. Great work AngularJS guys, cheers to you for creating such an amazing framework. Thank you and keep up the wonderful work :).