KO Your View Model With Knockout.js

Scroll Down

Written by Joel Tanzi

July 18, 2016

KO Your View Model With Knockout.js

Recently I was presented with a web application which required fixing up, which was a mishmash of a variety of frameworks and pre-processors, including Jade templates, Stylus, and CoffeeScript, and using Knockout.js for its view model. Knockout.js has proved to be the glue that really held this project together and I’ve gained a healthy respect for this framework, and I thought I might share a little of the insights I gained into why you might consider Knockout for a future project.

Knockout.js was developed by Steve Sanderson and released around 2010 with its most recent stable release in November of 2015 with a reasonably-sized community that is active on the usual sites like Stack Overflow, Reddit, and Google Groups. As a result it is not hard to find blog posts and discussions around how to use the framework for various tasks. It follows a Model-View-ViewModel (or MVVM) approach as a framework. Thankfully the framework is rather straightforward, once you wrap your mind around the concept of observables.

Consider this JavaScript object:

var person = { name: ‘Joel Tanzi’, favoriteColor: ‘Puce’, favoriteBook: ‘JavaScript: The Good Parts’, favoriteFood: ‘Korean short ribs’ };

Activating Knockout.js and making use of this object is quite simple:

<script> ko.applybindings(person); </script> <p>The other day I met <span data-bind=“text: name”></span> while I was playing mini-golf. <span data-bind=“text: name”></span> was in a swimming pool sitting in a <span data-bind=“text: favoriteColor”></span> lounge chair floating in the water, reading <span data-bind=“text: favoriteBook”></span> and consuming <span data-bind=“text: favoriteFood”></span> with great enthusiasm. “Welcome to my humble abode!” <span data-bind=“text: name”></span> said loudly and offered me some <span data-bind=“text: favoriteFood”></span>.

What is happening here is fairly obvious; Knockout is going to replace the text values of the span elements with the associated values of the object model person. But what if you want the flexibility of changing those values? Observables are your friend here, since an observable is basically a way to bind the value to an object model even when that value changes. Take a look at the following:

var person = { name: ko.observable(‘Joel Tanzi’), favoriteColor: ko.observable(‘Fuschia’), favoriteBook: ko.observable(‘How to Win Friends and Influence People’), favoriteFood: ko.observable(‘Monte Cristo sandwiches’) };

Now the same page I showed you above will display the same information, but the difference is that when any of the observables change, it will change the text within the span elements as well. That may not seem that remarkable on the face of it; after all, it’s not much different from any other variable when used in the manner above. But if you’re setting the value of your observables to those in a database that you are querying when load your page content, or tying Knockout observables to input fields in a form, the value of such dynamic bindings is much more obvious. Every element that uses this uses any of these data bindings will update its value to the that of the observables associated with them. This is just scratching the surface since Knockout really shines when you use two-way binding such as the ‘value’ binding that will alter the observable value or the DOM element form field value, depending on which one was altered.

Knockout can bind ‘click’ events as well, such as with the following example:

<button data-bind="click: function() { openMagicBox }">Click me</button>

This will call the ‘openMagicBox’ function defined in your view model when this button is clicked. It's as simple as that. One thing worth noting is that you could technically get away with using just "click: openMagicBox" in some cases. However, due to how Knockout is set up, this risks openMagicBox being called when the page loads. It is a better practice to wrap the function call in an anonymous function, as demonstrated above.

Data bindings don’t need to be specified within a DOM object; sometimes it is useful to have a data-binding that stands on its own. Knockout provides a way to set a binding on a set of objects:

<!-- ko if: enabled —> <div>I’m enabled! (Happy)</div> <!-- /ko —> <!-- ko if: !enabled —> <div>I’m not enabled. (Sad)</div> <!-- /ko —>

In the example above, the value of an observable named “enabled” will determine whether the first div or the second div is visible.

Some of you might be asking, why use Knockout instead of Angular? Angular is more powerful in many respects, but one downside is when you use it, it drives the design of your application around its framework. Knockout gives you greater flexibility. It is also makes for less complex code. It’s not a replacement for Angular, and it is not the best choice for large projects that need greater scalability. Knockout is also a convenient entry point for working with observables without having to learn Angular first.

There’s a lot I haven’t covered here that Knockout can do, such as two-way binding, templating, HTML manipulation, custom bindings, and more that you can review at knockout.js. For a comparison of features between Angular and Knockout, take look at this well-written piece by Tomas Kirda at devbridge.com.