Skip to main content Skip to footer

A ViewModel Walks Into a Bar and Gets Knocked Out

So what have you been up to, Griff?

Thanks for asking. I’ve been spending the past two weeks taking a good look at Knockout.js. It’s been one of the many technologies on my list to evaluate and learn, and I’m finally finding a little bit of time to do so. Good thing for you, I’m going to share what I’ve been learned.

It’s all about the MVVM, baby.

The term “MVVM” shouldn’t be new you. At least, I hope not. Model View ViewModel. Most people might go into this complicated spiel about how MVVM works from a conceptual level. I prefer looking at it from a more practical aspect. Have you ever written code like this:

$(“#txtUserFirstName”).val(“Kevin”);  
var userFirstName = $(“#txtUserFirstName”).val();

Wouldn’t it be much easier to just be able to do this?

model.userFirstName(“Kevin”);  
var userFirstName = model.userFirstName();

What’s the difference? In the first example, I’m looking at all my DOM objects directly and either getting or setting their values. jQuery is amazing at doing this, but why should we expend all this effort to just set a little bit of data. By using a model for the data on our page, we’re now putting everything into a single location. If I set userFirstName in the model, it can now be automatically updated anywhere on the page. I don’t have to write tedious getter and setter code for this property. This will make more sense as I walk through a simple demo.

Where To Get Knockout.js

This is the easy step: 1) Go to http://knockoutjs.com/ or 2) Download via NuGet Add the .js file to your page after the jQuery reference, and you’re good to go.

Creating a View Model

Everything beings and ends with the ViewModel.

function viewModel() {  
     this.firstName = ko.observable("Kevin");  
     this.lastName = ko.observable("Griffin");  
};

This shouldn't look too foreign. I have function that defines two properties: firstName and lastName. The assignments might look funny though. ko is the Knockout object, and we’re creating an observable object and assigning the value “Kevin” or “Griffin”. What’s observable mean? Let’s say I bind firstName to the value of a textbox on my page, and also the text of a span on my page. If I were to edit the value inside the textbox, it would automatically alter the value firstName in memory. At the same time, the span is observing changes to the value and will alter it’s text to what the value is. Let me show you how to bind elements:

Binding Elements to a View Model

<h1>Griff's Knockout Demo</h1>  

<p>First Name: <span data-bind="text: firstName"></span></p>  
<p>Last Name: <span data-bind="text: lastName"></span></p>  
<br/>  
<input data-bind="value: firstName, valueUpdate: 'afterkeydown'" />  
<input data-bind="value: lastName, valueUpdate: 'afterkeydown'" />

Here’s the example I outlined above. Two spans and two textboxes. Both contain data-bind attributes. These are what Knockout use to bind the model to elements on the page. Let’s examine the insides of the data-bind elements. For “First name” and “Last Name”, I’m telling Knockout to bind the text attribute of the span to the value of firstName. For the inputs, I’m doing the same except I’m telling Knockout to bind the value attribute of the input. I can bind multiple properties here by separating them with commas. The valueUpdate property is how Knockout knows it should update value in the model. Without this property set, valueUpdate defaults to when the input box loses focus. I like my pages to be in real time. There’s one more VERY IMPORTANT part to this puzzle. Knockout can’t read minds. We’ve set up the bindings, but we need to tell Knockout what view model we want to bind to.

$(function() {  
     var myViewModel = new viewModel();  
     ko.applyBindings(myViewModel);  
});​

In two lines of code, I’m creating a new instance of my viewModel and applying the bindings. By calling ko.applyBindings(), I’m telling it to search my DOM and look for any bindings that can be applied. Everything else magic.

Getters and Setters

Binding your elements is only part of the equation. You might want to update that data or get the current values to post to a server. How do you do that? Easy. If I want to GET the data from the firstName property:

this.firstName();

If I want to SET the firstName property:

this.firstName("Kevin");

More Information

I really hope this was a good introduction to Knockout. As you might know, Wijmo recently released support for Knockout. In an upcoming post, I’ll talk about how to use Wijmo and Knockout together to create sweet experiences. Here’s a link to the JSFiddle for the example. Visit http://knockoutjs.com for tutorials and demos galore! Kevin Griffin @1kevgriffkeving@componentone.com

MESCIUS inc.

comments powered by Disqus