How to get started with Knockout.js

Once you get into doing more client side JavaScript code with business applications and REST services you are going to run into the question of how to construct the client side HTML required to show the data to the users.

 

Using jQuery

Assuming most people are going to be using jQuery on the client you might start with some jQuery code to generate HTML.

Your code might look something like this

$(function () {


    $("#btn").click(function () {


        $.getJSON("/services/books").then(function (books) {


            $.each(books, function () {


                $("<li>").text(this.Title + " by " + this.Author).appendTo("#books");


            });


        });


    });


});

The code isn’t very complicated but then we are only showing a simple bit of text. And in all likelihood the actual HTML that needs to be generated will be quite a bit more complex. And the code increases as least as much, but often much more, in complexity.

 

Using templates

The next step people tend to take is using templates. There are lots of different templating libraries out there with more coming but in this example I am using the JavaScript Micro-Templating function John Resig wrote. If you are looking for others take a look at Underscore.js or JsRender/JsViews (still in preview at the moment). Specially Underscore.js is a nice library to look at because all the additional functions in there.

Using templates we separate the code from the template to generate the required HTML. The code is easier to understand.

$(function () {


    $("#btn").click(function () {


        $.getJSON("/services/books").then(function (books) {


            var html = tmpl("books_tmpl", { books: books });


            $("#books").html(html);


        });


    });


});

However this comes at a cost as we also need a template and that is a mixture of markup and expressions. The expressions syntax varies depending on the templating engine, in this case it’s <%= JavaScript Expression %>. Not hard to use but it is another bit of executing code that has to be maintained.

<script type="text/html" id="books_tmpl">


  <% for ( var i = 0; i < books.length; i++ ) { 


    var book = books[i];%>


    <li><a href="/services/books/<%=book.Id%>"><%=book.Title%> by <%=book.Author%></a></li>


  <% } %>


</script>


As you can see the template is actually embedded as a <script> block. Not a requirement as it is just a string but an easy way to do so. It does however mean that you have to handcraft the HTML with no designer or IntelliSense support.

 

Using Knockout.js

As soon as we start using Knockout.js this become somewhat more like Silverlight/WPF. Not that it is exactly the same but it uses the same MVVM pattern and data binding that Silverlight developers are used to. Something I really like Smile. Now Knockout.js is my no means the only way to do this, just as with templates there are plenty of other options like Backbone or JavaScriptMVC for example. See this blog post for a longer list of alternatives.

Personally I really like the MVVM and binding style Knockout.js uses.

Instead of splitting the HTML into a static and a dynamically generated part with Knockout.js you embed data binding expressions in your HTML. Notice the data-bind attributes in the following HTML snippet. They indicate data binding syntax. The first two data bind the value property of the <input> control to the firstName and lastName from the ViewModel. The third data binds the text in the <span> against the fullName of the ViewModel.

<fieldset>


    <legend>Enter person</legend>


    <p>


        First name:


        <input type="text" data-bind="value: firstName" />


    </p>


    <p>


        last name:


        <input type="text" data-bind="value: lastName" />


    </p>


    <p>


        Full name: <span data-bind="text: fullName"></span>


    </p>


</fieldset>

So what does the view model look like? It can be a real simple JavaScript object. In fact the following would work. It would be less than perfect thou and we can do better.

var viewModel = {


    firstName: "Maurice",


    lastName: "de Beijer",


    fullName: "Maurice de Beijer"


};

A better way is to use the Knockout functionality and define the data fields using observables. By using Observables we can observer changes being made. And by defining the fullName as a computed observable we can have the <span> with the fullName dynamically update. A much better ViewModel:

var viewModel = {};


viewModel.firstName = ko.observable("Maurice");


viewModel.lastName = ko.observable("de Beijer");


viewModel.fullName = ko.computed(function () {


    return viewModel.firstName() + " " + viewModel.lastName();


});

 

Of course we still need to tell Knockout to use the ViewModel and that takes all of one line:

ko.applyBindings(viewModel);

 

So the complete JavaScript in my page is now:

$(function () {


    var viewModel = {};


    viewModel.firstName = ko.observable("Maurice");


    viewModel.lastName = ko.observable("de Beijer");


    viewModel.fullName = ko.computed(function () {


        return viewModel.firstName() + " " + viewModel.lastName();


    });


 


    ko.applyBindings(viewModel);


});



 



And the nice thing is that updating the first name automatically updates the fullName Smile



image



 



This is just the first baby steps using Knockout.js as it is far more capable than just this. In fact we can data bind against arrays of data and create nice list etc. The Knockout.js site has some nice tutorials that will help you get started.



 



Enjoy!



 



[f1]
[f2]

Leave a Reply

Your email address will not be published. Required fields are marked *


*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>