In the previous two blog posts about getting started with Knockout.js and controlling updates using Knockout.js I showed to to get started with the awesome Knockout.js library. In this post I am going to show how easy it is to load a collection of items from a REST service and data bind to the complete collection.
To data bind to collections of data Knockout supports the foreach data binding. This lets us point at a collection of data and create a new item for each object in the collection. In the example below I am using an html <table> to display a list of books. The <tbody> has the data binding attribute so its contents are going to be repeated for each item in the collection being used, books in this case.
<table border="1">
<thead>
<tr>
<th>
Title
</th>
<th>
Author
</th>
</tr>
</thead>
<tbody data-bind="foreach: books">
<tr>
<td data-bind="text: title">
This will be the title
</td>
<td data-bind="text: author">
This will be the author
</td>
</tr>
</tbody>
</table>
So this looks, and is, very much like a data template but a little different. Normally when using JavaScript templates the actual template is stored as a string somewhere, often in a script block, and you don’t get to see anything until you actually use it. However in this case it is just HTML and without Knockout.js will be rendered as regular HTML. So if we just render this as is we get the following output in the browser.
Nice as this makes debugging the data template layout a lot easier.
Next we need to create a ViewModel and use Knockout to data bind it.
The basic ViewModel we need is really simple, all it needs to expose is a books array. To make sure the UI is updated with changes we don’t use a simple array but an observableArray as shown below. And if we call applyBindings() the data binding will be activated.
$(function () {
var viewModel = {};
viewModel.books = ko.observableArray();
ko.applyBindings(viewModel);
});
With this data binding is functional but we don’t have any data to display yet. As expected this results in an empty array. Notice the data template row is gone now.
Adding some data is easy. I have included a WCF Web API REST service here and the jQuery.getJSON() function makes it rather easy to consume the REST service with a few lines of code. In this case I am using the jQuery.each() function to process each object returned and I turn them into objects with observable properties, not strictly required here, and push them into the books observable array. This last push will cause the UI to update itself because of the data binding. The complete JavaScript code looks like this:
$(function () {
var viewModel = {};
viewModel.books = ko.observableArray();
ko.applyBindings(viewModel);
$.getJSON("/services/books").then(function (books) {
$.each(books, function () {
viewModel.books.push({
title: ko.observable(this.Title),
author: ko.observable(this.Author)
});
});
});
});
And the end result:
Sweet
Enjoy!
[f1]
[f2]