I've recently been working with KnockoutJS and have found it to be a very comfortable paradigm to use in constructing a web site. Having worked with XAML a good bit over the last few years, the benefits of MVVM have been made apparent to me time and again and the approach is familiar.
KnockoutJS lets you use very nearly the same MVVM approach you're used to using in WPF or Silverlight development. I've attached a sample application, below. Let's have a look at it.
If you run the sample application, you'll see the following web page open in the browser.

There is an editable table that allows the user to edit existing contacts. Clicking the Add Contact button adds a new blank row to the table.
The ViewModel
The project contains a Javascript file named ViewModel.cs, in the Scripts directory. The contexts of this file are listed below.
1: var viewModel = { 2: contacts : ko.observableArray([
3: { firstName : "Bob", lastName : "Marley" }, 4: { firstName : "Larry", lastName : "The Cable Guy" }, 5: { firstName : "Maxwell", lastName : "Smart" } 6: ]),
7:
8: addContact : function() { 9: this.contacts.push( { firstName : "", lastName : "" } ); 10: }
11: }
12:
13: $(document).ready(function() { 14:
15: ko.applyBindings(viewModel);
16: })
In the first code block, lines 1 – 11, we create a view model. In WPF or Silverlight, out view model would contain properties and commands that we could bind to in our view. The same is true with KnockoutJS. Here, we have a property that is a collection of contacts and a function (command). In lines 13 – 16, we ask Knockout to parse our view and connect the data bindings to our view model.
Notice that our property is an instance of an observableArray. In XAML data binding, we have the concept of the view and view model communicating with one another where events are raised when values change so that data and the controls bound to it stay in sync. This same functionality is encapsulated in the observableArray for arrays and observable for simple properties. So, modifying a bound property from the view model will cause a control in the view that is bound to the property to change, as well. The reverse is also true, modifying the contents of the control will update the view model property.
The View
1: @{ 2: Layout = null;
3: }
4:
5: <!DOCTYPE html>
6: <html>
7: <head>
8: <title>Index</title>
9: <script src="../../Scripts/jquery-1.5.1.js" type="text/javascript"></script>
10: <script src="../../Scripts/jQuery.tmpl.js" type="text/javascript"></script>
11: <script src="../../Scripts/knockout-1.2.1.js" type="text/javascript"></script>
12: <script src="../../Scripts/ViewModel.js" type="text/javascript"></script>
13: </head>
14: <body>
15: <div>
16: <fieldset>
17: <legend>Email Addresses</legend>
18:
19: <table>
20: <thead>
21: <tr>
22: <th>First Name</th>
23: <th>Last Name</th>
24: </tr>
25: </thead>
26: <tbody
27: data-bind='template: { name: "contactRowTemplate", foreach: contacts }'> 28: </tbody>
29: </table>
30:
31: <button data-bind="click: addContact">Add Contact</button>
32:
33: <script type="text/html" id="contactRowTemplate">
34: <tr>
35: <td><input class="required"
36: data-bind="value: firstName, uniqueName: false"/></td>
37: <td><input class="required"
38: data-bind="value: lastName, uniqueName: false"/></td>
39: </tr>
40: </script>
41:
42: </fieldset>
43: </div>
44: </body>
45: </html>
We start by setting up our html table. All probably looks familiar up to line 27. In Xaml, we use Binding expressions to state what we want to bind to and how that binding is to behave. KnockoutJS uses the "data-bind" attribute to specify these bindings. In line 27 a binding is expresses that says, "for each item in the collection of contacts on the view model, create and populate an instance of the template named 'contactRowTemplate'". You can see the template definition in lines 33 – 40.
Compare this binding with a similar Xaml binding and you'll find:
- It's possible to do an ItemsSource type binding in KnockoutJS where an item is generated for each entry in an array.
- Adding or removing an item from the array causes row corresponding to that item to appear or disappear respectively.
- A template can be specified for how each item in the list will be constructed. Compare this with the ability to specify an ItemTemplate in Xaml (note that you can organize the container of the list as you wish which is very similar to ControlTemplate's.
- In Xaml, the data context flows in a predictable way through all an item's sub-items. Note that the binding on the <tbody> element is to an array and the bindings inside the template are to a single item in the array. This behaves the same as in Xaml.
The button in line 31 uses a click binding to bind the click event to the function we defined on our view model.
Yes, the binding syntax is different and there are many more binding types available than are used in this simple sample, but the library is very well documented here and the familiarity of the MVVM approach to constructing a UI make KnockoutJS a very easy library to get started with.