Introduction to KnockoutJS

Introduction

Modern applications today tend to be very complex and offer a plethora of features. As such, developers must constantly strive to find a good balance per the separation of concerns to create solid applications and enable good unit testing.  Because of these needs MVC has returned to the forefront in recent years as a way to achieve this separation.  However, with Ajax there is more logic within the view interns of how the view should work for the user.  With traditional MVC this leads to a lot of code being placed in the View to facilitate these interactions.  This leads to a lot of extra code being put in the view and developers asking the question “should there be another layer somewhere?”.

Enter MVVM

As part of the .NET 3.0 release Microsoft began work on the Microsoft Windows Presentation Foundation (WPF).  This new framework used a declarative markup language (XAML) to build user interfaces, this meant that the code previously hidden in Windows Form for creating controls and placing them was removed.  Perhaps once of the most profound things to come out of this framework was the notion of declarative binding.  Whether this was actually invented here is unknown to me, it is simply the first example I saw of it.

Using these declarative bindings we (developers) were able to remove much of the get/set code that had created so much clutter over the years. This formed the basis for the Model View ViewModel pattern (MVVM) where we actually split the V into the View and the ViewModel.  The ViewModel taking on much of the code that had originally cluttered our views, thus becoming the new layer we so desperately sought.

MVVM on the Web

One of the strategies that developers use with MVC on the web to do MVVM is the use of strongly typed views.  Frameworks like ASP .NET MVC and Ruby on Rails, allow developers to base their views on a class passed to the view, often referred to as the View Model in this context.  While not MVVM in the purest sense, the intention is the same, separate out the data from the actual view and provided an automated way to update the values without needing to write tedious plumbing code (see Model Binders in ASP .NET MVC).  While this works for simple applications, it falls well short when used with Ajax heavy applications due to the reliance on JavaScript and the lack of behavioral definitions in the strongly typed “view model”.

Frameworks like JQuery have come to prominence for their ability to make JavaScript easier to use, it has also led to more applications relying on JavaScript as a means of communication and UI enhancement.  And while this is true, it has also led to MORE JavaScript being written to support these interactions.  Thus the same problem began to present itself in the view.  It has become bloated with tedious repetitive code. And since JavaScript, by its nature, does not architect well, the problem gets even worse.  The purpose of JQuery was to allow us to do more but writing less.  While it does achieve that, it also adds a reliance on JavaScript that creates its own set of problems.

KnockoutJS

Thankfully this problem has not gone unnoticed by the community, frameworks already exists to bring the MVVm approach to JavaScript applications.  KnockoutJS (http://www.knockoutjs.com) is one such framework.  It takes the approach that the view should be as clean as possible, devoid of any JavaScript.  To do this, it leverages the new “data-bind” attribute in HTML5, while maintaining backward compatibility with HTML4.  Take a look at the sample code below:

NewImage

This is a very basic example, but what it does is “bind” the FirstName and LastName members of the “viewModel” object.  This example is showing off one way binding, since the user cannot expect to update the text content of a .  So if we want to use two way binding, we would need to use the binding with form elements:

NewImage 

A few things are happening here.  First, we are using a different way of denoting a JavaScript “class” definition.  Since functions in JavaScript can also be treated as object constructors, we can use the new keyword to denote a new instance.  Thus far, I would not take any of the lessons of OO programming with you in JS.  The second thing to notice is the value: binding.  KnockoutJS comes with many of these built in bindings, which will usually be enough for most projects.  A complete list can be found at http://www.knockoutjs.com along with a plethora of examples.

By itself the value: binding will not give you the two way binding you would want on a form textfield, in fact it has very little to do with the two way binding you want.  The key for two way binding is the user of Knockout Observables.  If you notice the definition of our object contains two refers to ko.observable.  Using this makes the member special.  It tells Knockout to watch this binding for changes and update the view model when changes occur.

In the AppViewModel object, we are also defining a “computed” observable.  This will watch a field (or fields) for changes and update accordingly.  There are common used for composed properties which use the data from a variety of other properties (or members).  In the case of this example, any change to the value of firstName or lastName will update the value in fullName and cause the to update its value to display the changed value.  Side note: buy default, for value: the binding update occurs onBlur as opposed to onKeyDown, this is configurable.

With our current example, when you blur out of a textfield the span will update, but what would we have to do for the update to be real time, as they are typing.  Simple, we specify the valueUpdate setting on the binding:

NewImage

As you can see, we specify that the update to the view model should occur after key down.  This will automatically handle everything for us and since we are updating the view model which is using a computed observable this change is then immediately reflected in the tag.  So without writing any JS code, we have achieved this effect.

Conclusion

Lets me realistic, web applications are complicated.  The bar for interactivity is now higher than ever, but JS remains a fragile and fickle language to work with.  The project I am currently on is using utilizing PhoneGap to attempt to deliver a single code base to both iOS and Android.  The approach is heavily reliant on JavaScript.  Already the team has seen value in using Knockout because they get to write less JS code, which is always a good thing.  Furthermore, using a view model approach allows you to write unit tests, yes I said unit tests and JavaScript, which further allows you to ensure that the application works.  JS is one of those languages that is just a bitch to do anything in unless you maintain tight control over the architecture, so it is true on our app as well.

The MVVM approach to View development is something that I highly recommend.  The biggest thing people seem to have trouble with is they want to view it as a replacement for something like MVC.  It isn’t.  Its a augmentation.  The M in MVVM (Model) only refers to the output of a Controller, not a Model from MVC, although it could.  The principle point of emphasis in MVVM in that the ViewModel handles the interactions.  ViewModels handle client validation and view interaction, they don’t do any kind of persistence, although they can be backed by a Model which does provide some level of persistence.

 

Leave a comment