Sunday, April 27, 2014

Angular JS and Knockout JS



KnockoutJS vs AngularJS 

Luckily (or unluckily ? ), I keep getting opportunities to work with everything other than Angular. In my latest assignment, I have had the opportunity to work with Knockout. I have to say that I liked it and would have picked Knockout as my favorite framework if Angular did not exist.

People keep asking these questions and probably there is a good reason for it. Humans hate choices. If there are resources out there which help them make these choices easier, they like it. So, if you havent already tried the two frameworks, here are some comparisons/differences betwen the two.

Templating

Angular and Knockout both provide DOM based templating.

Angular only supports HTML as its templating mechanism.

Knockout by default uses HTML as its templating mechanism ( which is where they both have DOM based templating ) , but Knockout also supports other string based templating engines like Handlebars etc (but I think hardly anyone uses that!).

Unobtrusive

Knockout tries to please people who are interested in Unobtrusive Stuff.. http://knockoutjs.com/documentation/unobtrusive-event-handling.html

Angular doesnt believe in it ( or the authors of angular do not make any exceptions to provide for unobtrusive cases. )

Context

In knockout, in order to fetch data from a context that is in the parent of your current context, you need to access it using `$parent`.

In angular, context’s inherit prototypically. So, to access something from the parent context, you dont usually have to use $parent . You only need to use $parent if you have another variable with the same name defined in your current context as well.

Directives or Custom Bindings

Angular has directives. You can define custom elements, custom attributes, comments and classes.

Knockout doesnt allow you to create custom elements. You have to create all your bindings inside data-bind. ( I am not sure about this. Someone can correct me if I am wrong! ).

JQuery Dependency

Angular has its own version of JQuery called JQueryLite ( smaller jquery). If you include JQuery before Angular, it will use the JQuery you loaded.

Knockout does not depend on JQuery or create its own version of it. But, having said that, Knockout is a data-binding library. It does not have any opinions or implementations for doing Ajax or DOM querying. If you don’t include JQuery, you are free to do ajax and DOM manipulation either directly or with some other library.

Partitioning or creating new contexts

Angular has a concept of controllers which allow you to create new contexts explicitly. Angular also implicitly creates context’s when using ng-repeat, ng-switch, ng-include etc. Angular’s controllers, services and its concept of DI make it extremely easy to partition and manage large applications.

Knockout doesnt allow you to create contexts explicitly (Unless you create custom bindings). Knockout implicitly creates new contexts when using for-each etc.. This also means that Knockout has no opinion regarding the overall structure of your application. Without careful planning its easy to “mess up” your code base with Knockout.

Browser support

Angular supports all new browsers and its support goes back till IE8.

Knockout supports till IE6.

Batteries included

Angular is a full fledged framework. It provides dependency injection, ajax, routing, cookies, promises and much more.. Angular is great for testing.

Knockout is a data-binding library. To go for a full fledged framework have a look at DurandalJS – which is a combination of Knockout, JQuery and RequireJS. Knockout was not built with testing in mind. So, it doesnt score soo many points in that department. But still, I think it wont be terrible.

Documentation

Angular documentation covers pretty much everything it has. Angular is huge.. Its a shift in paradigm.. in the way of thinking itself. So, no matter how much documentation you have ( and we dont have enough ! ) you will always want more.. Certain core pieces are missing from the documentation.

Knockout’s documentation is the most praised in the community. But… ( yes, there is a but! )… Knockouts documentation for all the binding syntax is amazing, extensive.. But, when it comes to the utilities that knockout provides, there is zilch.. No where can you find documentation for those.. Either the documentation doesn’t exist or it is in such an obscure place that its hard to find.

IDE support and debugging support

Angular has amazing plugins available for all Intellij IDE’s. There is also a plugin available for Visual studio, which I believe is a port of the Intellij plugin. Angular also has a Google Chrome extension called Angular Batarang which allows you to select any element in the developer tools window and preview its scope variables.

Knockout doesnt have any popular IDE plugins which help in developer productivity.. I believe it is mostly because it used a single data-* attribute as opposed to Angular which uses different data-* attributes for different tasks. In terms of plugins, Knockout too has a Google Chrome extension, but I am not sure it works as seamlessly as the Angular Batarang. I tried it, did not work very well for my use cases, so I dropped it.

If you want to debug knockout in your browser, here is a tip (Google Chrome):F12 ( Open developer tools ) Select / Click on the element you want to inspect.

Open the console.

The current highlighted element is available in the console as $0

In the console, typevar context = ko.contextFor($0); context

context will now have your context information for that element. This context will give you ideas of what and how you could use it in the data-bind attribute.

Community Support

Ok, this is going to be controversial. But, I believe this is based on facts. So here it is.

Angular has a bigger community. No doubts about it. If you ask a question, there is a high probability you will get an answer.

Knockout has a comparatively much smaller community.

For me the measure of an open source projects community is a function of 3 things.

1. Github stars and forks

2. Stack Overflow questions

3. Google groups – number of posts per week and number of members.

Angular wins hands down in 1 and 2. In SO questions category, they are very close.

Ease

You should understand that Angular is a full fledged framework while Knockout is a data-binding library. There are way too many concepts in Angular and it forces you into a totally different way of thinking. This is not easy.

Learning knockout is easy. The simple things atleast. I think one of the problems with Knockout is that there aren’t many articles / blogs about it. Not in the 100′s atleast. If you need to do something obscure, you are on your own. Ofcourse asking about it on SO will help. The same is also true about Angular. But, there is a subtle difference. Angular is meant for these obscure things.. custom bindings etc.. So , over time you will find more and more documentation and blogs for it. All over the world wide web, if you look for Angular, you will see people talking about directives.. which are custom bindings.. Not the same case with custom bindings in Knockout. I am sure people use it, but they just dont talk about it much.

Variable Observation

Angular observes variables using a technique called as dirty checking. On the other hand, Knockout uses the Observable pattern. In terms of code

Angular HTML :

1 <div ng-bind="myContent"></div>
or
1
<div>{{myContent}}</div>
Angular javascript :
1 $scope.myContent = "Hello World";
Knockout HTML :
1 <div data-bind="text : myContent"></div>
Knockout Javascript :
var myContent = ko.observable("Hello World");
To change this content..
In Angular :
$scope.myContent = "Hello You";
In Knockout :
myContent("Hello You")
Events and custom parameter passing :

Angular HTML
<button data-ng-click="onButtonClick($event,'save')">Save</button>


<button data-ng-click="onButtonClick($event,'cancel')">Cancel</button>

Angular Javascript
$scope.onButtonClick = function(event,action){
// your code.
};
Knockout HTML
<button data-bind="click : onButtonClick.bind($root,'save')">Save</button>
<button data-bind="click : onButtonClick.bind($root,'cancel')">Cancel</button>
or
<button data-bind="click: function(data, event) { onButtonClick('save',data, event) }">Save</button>
<button data-bind="click: function(data, event) { onButtonClick('cancel',data, event) }">Cancel</button>

Conclusion

I love similes and metaphor’s. In my Angular vs Backbone post, I said that if Angular could be consider a Motor Boat with all its complexities in machinery and mechanism, Backbone could be compared to a Life Jacket. Backbone forces you not to drown, which is why it was compared to a Life Jacket. Knockout’s focus isnt about your drowning. It is about your speed which is why it doesn’t care whether you drown or not. Images are better than words.. So here is the comparison.

No comments:

Post a Comment