In a number of casual–and sometimes not-so-casual (!)–discussions about client-side JavaScript libraries, I’ve noticed that people have an unfortunate tendency to lump them all into a single amorphous blob. Backbone? Ember? Angular? Knockout? They all do something-or-other involving structuration on the front end; they’re all more or less the same thing.

WRONG!!!

There are indeed deep similarities between these libraries in terms of what they offer developers, but understanding their differences means understanding which use cases they’re best suited for. Here, I’ll make a foray into this discussion by outlining some of the basic characteristics of Knockout.js I’ve discussed Backbone previously, and I’ll discuss the others in a future post.

According to Knockout creator Steve Sanderson in this video, Knockout, like many other libraries, was meant to provide “rich client-side interactivity.” HTML and the DOM are never ever ever going to provide you this on their own. What you see is what you get. In 1992, that was just fine. In 2012 we expect a whole lot of interactivity on the client side, but this kind of interactivity can’t be built on sand. Doesn’t a library like jQuery get us there? Well, not quite.

Binding jQuery to an underlying data structure

Knockout is a library that essentially enables you to produce an abstraction layer that ties changes in your view to changes in values within that layer. To put it in simpler terms, Knockout was designed to overcome some of the limitations inherent in jQuery. In the words of the Knockout website, jQuery is a wonderful way of enabling you to easily manipulate the DOM, but it “doesn’t have a concept of an underlying data model.”

This in no way means that jQuery is “bad.” It simply means that manipulating the DOM using jQuery alone demands that you do everything directly and by hand. If you want an event to take place within the DOM–say, changing the background color of a header–you have to use a jQuery command such as toggleClass to make that happen.

For many use cases, that’s just fine, but often there needs to be a systematic connection between changes in your views and a data model underlying a page. In highly dynamic apps, you often want changes in your views to be directly and immediately responsive to changes in your data model (which I have discussed elsewhere) without a jQuery intermediary. Knockout is special because it enables you to create things like direct data binds to DOM elements. If I want a paragraph to change its contents in response to the value of the variable par, I need only do the following:

<p data-bind="text: par"></p>

Behind the scenes, all we need to do to make the variable par capable of appearing in the view is to make it observable:

var par = ko.observable();
If I set up an event chain in which clicking a button changes the value of par, then that change will transpire immediately in the p element to which I’ve applied the bind. Let’s try binding a list to an array. The array in question will be called threeStooges:
var threeStooges = [ “Larry”, “Moe”, “Curly” ];
We’ll bind the array directly to an unordered list and use the foreach command to cycle through the different array elements:

<ul data-bind="foreach: threeStooges">
    <li data-bind="text: $data"></li>
</ul>

That’s it. No awkward “for” loops, no jQuery {{ }} brackets. And the bindings happen internal to your HTML markup rather than being dictated from outside of it (as in Backbone).

Basic architecture

So far, we’ve seen two simple illustrations of Knockout’s MVVM architecture (model-view-view model) in action. I know what you might be thinking: Oh, come on. Another new architecture that I have to understand? But not to worry. It’s actually very simple.

Addy Osmani helpfully defines the MVVM (Model-View-ViewModel) pattern here as one in which “the ViewModel provides data bindings between the Model and View.” This pattern is virtually identical to the Model-View-Presenter pattern attributed to Martin Fowler. In both patterns, the view is essentially how your page ends up looking (including all the different possible permutations of your page); your model consists of the different variables that are intended to make a difference in your view, as well as all of their possible values; and your view model, in turn, consists of how the view and the model are synced up with one another.

As we’ve seen, Knockout binds views and models together with data bindings. These bindings basically “sense” for changes in the underlying view model and then immediately change the view in response to those changes. This is the not-even-rendering that I refer to in the title of this post. I call it this because I’m not quite sure what else to call it. I was tempted to call it “I can’t believe it’s not rendering,” but better judgment prevailed (whew). It’s like rendering in that it’s changing the visual appearance of the page, but it’s doing so without asking the server for any new information whatsoever.

When the page finishes loading, the browser already has all the information that it needs to change the view in light of changes in the data model. You might sacrifice a bit in terms of up-front loading time in certain cases, but it’s easy to imagine situations where this is more than worthwhile. And as browsers become more and more powerful–and better and better at using JavaScript–this will become less and less of a consideration in the coming years.

Knockout vs. Backbone in a Pinterest clone

Not only is it difficult for me to imagine how something like the AppFog console could be mustered with jQuery alone, but also using another front-end library like Backbone. Backbone is incredibly useful and cool, but Knockout and Backbone and do subtly different things, and grasping that distinction could mean saving yourself a lot of time gobbled up by using one when you should have been using the other.

I’ll illustrate the distinction between the two using the AppFog console example from before and a stripped-down, JavaScript-only version of Pinterest (which I’m not supposed to love but do anyway).

For the AppFog console, Knockout is clearly superior. I’m not even sure how one would begin to construct it using Backbone for several reasons, foremost among them because Backbone was built to enable you to manipulate multiple objects that share a data model.

If you need to load, create, modify, or delete them in accordance with a pre-specified model, then Backbone is the way to go. If we wanted to build the AppFog console to be able to have multiple consoles running on a single page, then Backbone might be a good way of making that happen. In that case, the whole console would be taken as a data model/template to be used to produce new consoles on the page.

It would also be great if we were making a really basic imitation of Pinterest. In that case, we would be primarily interested in producing new “pins” according to a data model. Using Backbone, we could construct our model like this:

var Pin = Backbone.Model.extend({
    ...insert model characteristics like height, width, etc....
});

From there, we could add new pins to the page using the Pin model as our template:

var newPin = new Pin({ ...specific characteristics of the pin... });

Here, every single pin that we would ever use would be predictable in how it is structured. Every pin would have a user who posted it, an associated image, a caption to the image, appended comments, etc. We could even explicitly specify that any object that does not have an image of a certain size, a title, and so on, simply doesn’t count as a pin and is not allowed to show up on the page.

Knockout enables you to use models as well, of course, but if you want to build something like this, where you’re generating lots and lots of objects according to a pre-specified data pattern, then Backbone might be a better tool. Another turn-off for some developers is that Knockout can only use its magic if you embed its logic within your HTML.

Without going into specific HTML tags and implanting data binds and other Knockout-based logic there, there isn’t a lot that you can do with Knockout. With Backbone, on the other hand, your HTML body could hypothetically consist of little more than an empty div element that you could use as an empty container for your entire view logic. If you’re insistent upon having as clean a separation as possible between your HTML and your view logic, then Knockout might not be for you.

If, on the other hand, your page needs to be full of interface elements like buttons and knobs (or their equivalent) that enable users of the page to change the values of underlying variables and produce immediate visual effects, as in the AppFog console, then it’s difficult for me to imagine Backbone being useful for that.

Fortunately, there’s no reason why Backbone and Knockout can’t co-exist. They can both be relied on to produce the same page. There even exists a library, Knockback.js, that is intended to do precisely that. If AppFog needed to enable people to click a button and produce multiple consoles on the screen that are cut from the same model pattern, then Backbone might provide a convenient way of doing so. In that case, we could produce consoles by declaring a Console model in Backbone and reproducing new consoles in freshly-generated generic empty div elements.

So that’s Knockout in a nutshell: a tool that allows you to produce an input-output matrix, consisting of variable values directly linked to representational content, that hovers over the DOM and structures how DOM elements respond to events (like clicks or text inputs into forms). The DOM was never built as a mechanism for storing application state. If you want it to do so, you’re going to need some help, and Knockout is on the scene to provide it.

Powerful stuff.

Note: I’ve obviously just scraped the surface of the power of Knockout in this post. Expect a follow-up post soon!