Introduction

Knockout, developed by Steve Sanderson, is free open source JavaScript library available under MIT license. It was first released in 2010 and since its initial release it has caught attention of industry and has been very popular. It is written purely in JavaScript and works on any web platform, any web browser and has no other dependencies. Features like easy bindings, observables and template support makes it truly unique and very useful for any enterprise application. It’s very robust and takes care of lot of heavy lifting for your application and provides an elegance interface to build apps. It was developed with keeping Model-View-View Model in mind. Note that, it’s not replacement of jQuery and it doesn’t help low level DOM manipulation and event handling, rather it addresses a totally different problem related to UI to Data manipulation.

At a very high level Knockout offers:

Ø Declarative bindings of UI controls to your Data model

Ø Automatic UI refresh based on your data

Ø Dependency Tracking

Ø Template support

Bindings:

To understand the simplicity and power and knockout bindings, imagine a simple scenario where you have to display employee information on UI:

If I choose to do this without knockout, then I will write something like below:

This is just to show data on the page, if we were to save the updated data, then again few more lines of code for save operation too. The more the information, the more the javascript. I have to keep track of all the data that is being displayed and save after it has been submitted. This situation leads to unmanaged Javascript code over the period of time. We don’t want out code to be unmanaged or messy.

Well, fortunately, knockout has a solution for us. Let’s take the exact same problem and we will try to solve it with Knockout this time.

In the sample code shown above, we have declared our UI bindings using data-bind attribute, note that property names are directly bind’d here, and then in scripts we have our view-model with some default data. Now the most important thing is the saveToJson method in which we are using a knockout helper method ko.toJSON which returns json data for any object. Now you can take this json data and pass it to server to perform save operation. Cool…isn’t it?

You can keep extending your UI for more information (like address, phone number and personal information) and just update your binding, that’s all! Knockout will keep track of your UI and data for you. As you see it takes care of all the heavy lifting’s for you and provides you a simple interface to hook up your view model. The end result is also very convincing, a clean and better way of doing things.

Observables:

Observable is another powerful feature of Knockout. Observables are declared using ko.observable() function call and then knockout keeps track of its value. You can extend observables to update other objects, properties, raise events and even perform validation on entered value. Let’s take a very simple example of asking user first name and last name and printing the full name.

Check out the above code snippet, we are not doing much and yet we have everything working. Unlike jquery, neither we are capturing any events nor we are worrying about data manipulation, knockout is doing everything for us.

Let’s review the code above to understand how it’s working without much JavaScript code. The very first thing is the HTML markup, in which we have controls and binding information, the only extra thing I have done in this sample is to add a valueupdate event, which will be fired as soon as client updates anything on the UI for that binding. This is to get real time updates from UI. Next is, View model, which has two properties and both of them are observables. Define a property as observable, if you want knockout to keep track of its value, this is pretty much like two-way binding in Silverlight. Lastly, the interesting piece, full name property which is actually a computed function – so in knockout world, if you have any such properties that you want knockout to calculate at runtime, then, you should use ko.computed property descriptor. It will hook up all the dependent observables on the computed property and anytime dependent observable’s value changes, it re calculates the computed property. So anytime, first name or last name changes, knockout updates full name automatically. (Check out the – 03-Observables.html page for actual implementation in sample project linked with this article).

Observable Arrays:

Just like the observables seen before, observable arrays target complex arrays. Knockout has great support for observing complex arrays, and you can certainly define chain of dependency tracking. I’m going to show you how easily knockout handles chain of dependencies in the example shown below:

As you see in the example, our view model has a collection of companies and each company object has a collection of employees. There is nothing fancy in the array but our UI markup has something new which we didn’t see earlier. Knockout has in-built support for collections using “foreach” data bind attribute to loop through all the elements of an array. Once you define any such binding, knockout knows that it has to repeat the UI markup for each of the elements in that array. Not only does it handle the looping iterations elegantly but it also manages the context very well. So for instance, the outer loop (foreach) has company object specific bindings and inside, we have employee object specific binding. Knockout knows exactly how to change the context and which events to plug in at runtime so that correct events are trigged at runtime.

Automatic UI Refresh:

Automatic UI refresh is one of the coolest feature of Knockout. As the name suggests, it refreshes the UI automatically when the underlying data changes. The example discussed in above feature also shows the Automatic UI refresh feature, but I’m going to take a different scenario from real world to show you that it’s indeed a coolest feature ever.

The very first thing to notice from the sample above is the separation of concerns, my initial data (Model) is separate from View model and UI markup, in real world, you would want to keep your model providers, View Model and HTML markup in a separate files, so that you achieve good control over separations. After you run the (05-Automatic UI Refresh.html) file from sample project you would notice that, after you click on add or delete buttons the UI refreshes automatically when in reality we are only manipulating the data. Any changes to data are being tracked down on UI and vice versa. This is happening because through bindings knockout knows which html element a data property is mapped to and what to do when any of the data or UI changes.

Template support:

Templates are a simple and convenient way to build sophisticated UI structures. It is one of the most powerful feature of Knockout. It supports several JS template engines like jQuery.tmpl, underscore.js out of the box. To define a template rendering in knockout, use data bind attribute to specify template name and corresponding action with data. As shown in sample below – we have a simple table, which has templates defined. That’s all the html markup we have in this sample. Rest everything is simple JavaScript.

Templates are defined in script block with a script-type little different than usual. This is tell browsers not to execute this immediately, we would like knockout to compose this template when needed at runtime.

Finally, our view model, which is a regular knockout view model with some sample data. Note that actual logic of rendering UI lies with knockout template engine. It will take the instructions from UI markup and render the UI and plug in necessary DOM events. Template support is a simple and yet very powerful feature of knockout which could be extended to build high performing enterprise apps.

Conclusion:

By now, we have seen all the important features of knockout, and you can really tell its potential. Check out the sample code provided with this article to see knockout in action. A quick recap of whatever we have seen before, Knockout offers –

6. Plug in support – external plugins like validation, mapping, typescript and many more makes integration and extension with any other JS framework very easy

Lastly, knockout lets you think in terms of your data rather than controls and events. Next time you have a web page to display some data, think in terms of your domain object, use knockout to display and manipulate the data, after the user has done editing, send the object back to server in JSON format.

Knockout is simple and yet very powerful library and comes handy in web application development. Try it out in your next project to take advantage in terms of developer productiveness, better control over your data and doing more with less code.