Sunday, September 20, 2015

Understanding Knockout

What's the Goal?

I once worked with a man who, when discussions of a solution turned confusing, would always ask, "What's the goal?" It is surprising how often we see a problem and try to find a solution without really understanding what solving the problem really means. The problem that we had in AJAX apps is that our data was stored in the DOM, and we would always be fiddling with sometimes-complicated widgets there to do conceptually simple things. And the entanglement meant that changing superficial presentation things might require wide-ranging changes to the code.

The goal, then, is to separate presentation (the view) from data (the model). Numerous libraries exist to solve this problem, but most of them threw in several other goals, leading to over structured and indirect solutions to the problem. Knockout focuses on this one goal, and as a result is easy to learn and easy to read.

The Knockout Approach

Knockout says that there are two types of JavaScript in an application: the ViewModel and the Bindings. The Bindings exist to synchronize the ViewModel and the View: changes in the View that are made by the User will be reflected in the ViewModel, and changes in the ViewModel will be reflected in the View.

Because Knockout guarantees the View and the ViewModel will always be synchronized, there is never any reason for you to reach around the Bindings and manipulate the View. That means you're never going to use a jQuery selector outside of a binding. If you are selecting elements of the DOM, stop and ask yourself why you are not dealing with the corresponding element of the ViewModel.

What's a ViewModel?

The ViewModel is a collection of variables that represent everything that can change in the View. Instead of manipulating DOM elements, you manipulate the variables, and the Bindings update the DOM for you automatically. And if the User changes some setting in the DOM, the Bindings update your variables for you.

What's a Binding?

A Binding (or binding handler) is the code that understands how an element of the View should reflect (and be reflected by) ViewModel variables. Knockout comes equipped with a number of the most common types, but you should expect that you will need others to handle specialized widgets. Happily, bindings for many well-known widgets have been written and are available on GitHub (and elsewhere). Still, you should expect that you will need to write some of your own. It is no more difficult than writing DOM manipulation code that isn't part of a binding. Knockmeout has a great writeup on writing custom binding handlers.

Where's the Model?

Some people have (rightly) noted that, although Knockout is billed as an MVVM (Model-View-ViewModel) system, it's not obvious where the Model part is. You model the application you are building with your ViewModel. Any data you work with is part of that, but does not necessarily require being separated from the rest of the ViewModel. That is up to you. Always ask yourself, "What's the goal?"