Knockout.js – cleaning up the client-side

>I’ve started a new project with a client and it’s quite a shift for me. Coming off a heavy client (WinForms), 3-year project I’m now working in ASP.NET MVC and javascript. One of my goals with regards to the architecture was to keep a handle on the javascript. The project is integrating with the ESRI ArcGIS Javascript API and so there will be lots of client-side javascript and it will be important to keep it organized and maintainable.

In looking around for javascript libraries to help with this I found Knockout.js. This is a library for building larger-scale web applications that use javascript more heavily.

Knockout works by extending the properties of your javascript models (basically a POJO… Plain Old Javascript Object). You can then bind your model to the view (HTML elements) by marking up the HTML elements using “knockout bindings” (there are quite a few to choose from and they’re listed here). Basically a knockout binding is a way to bind a property on your model to a specific attribute of an HTML element. There are quite a few that come built into Knockout (including things like text, visible, css, click, etc).

Once you’ve got the view marked up you simply call

ko.applyBindings(model);

and Knockout takes it the rest of the way.

Let’s walk through a simple example as that’ll make things more clear (I’m going to use the same Login UI example as Derick Bailey used for his first Backbone.js post so it’s a bit easier to compare apples-to-apples… hopefully).

The layout is very similar to a Backbone view except that in a Knockout view you add extra ‘data-bind’ attributes.

Notice the ‘data-bind’ attributes in the markup. These dictate how knockout will bind the model we provide to the UI. Let’s move on to the model now.

This is very close to being a simple javascript object. The only trick is that any property that we want to bind to the UI should be initialized via the ko.observable() method. The value we pass to the ko.observable() will become the property’s underlying value.

Once we’ve instantiated a model object we simply call ko.applyBindings() and Knockout does the rest. (Note that the second parameter is the HTML element that should be the root of the binding. It is optional if you are only binding one object to your page, but I think in almost any application you’ll get to a point where you want to bind multiple objects so this shows how to do that.)

At this point Knockout will keep the UI and model in sync as we manipulate it. This is full 2-way binding for the text elements. So if the user types in the username field, the model’s username property is updated. If we update the model’s username property the UI will be updated as well.

Derick noted in his blog post the mixing of jQuery and Backbone.js. I’m doing some of that here, but I think Knockout.js doesn’t need jQuery as much because of how the binding is declared (on the HTML elements themselves).

I’m going to try to follow Derick’s excellent series of posts on Backbone.js and comment on how the subjects he discusses compare and contrast with Knockout.js.

In the end I think both are very capable libraries even if they come at the problem from slightly different angles. In the end it’s all about better organization of javascript and better assignment of responsibilities in the javascript you write.

Advertisements