I came through an open source JavaScript named as “Knockout.js”. After learning this javascript functionality and features. I found it very powerful, when it is used combined with jquery.js. and jquery.tmpl.js. It gives us a JavaScript object named as “ko” that has powerful methods and cool utility methods. I found that knockout helps us to write JavaScript code in MVVM pattern that is very neat and clean object oriented coding practices and pattern. By using ko, you can create your own ViewModel JavaScript object and bind that object with your DOM element. Changes into the DOM element value will dynamically reflect into the ViewModel object and it is vice versa. It is kind of one/ two way data bindings with the DOM element and ViewModel object. For linking with the value of the DOM element and ViewModel object you have given “data-bind” attribute from ko object. It’s data linking functionality is very similar to datalink.js. However, it is not just data binding things that you can achieve using knockout.js. Knockout goes little bit above to that. It has few more advantages like over data linking as:

1) Automatic Dependency Tracking.

2) Declarative Binding

3) Integrated Templating

4) Re-rendering the template. Instead of rendering all element it can re-rendered the only element which is being updated. I am going to write few methods and behavior of knockout.js.

One Way Data Binding

You can use observable() method to make certain DOM element to be observable. That means, if observable DOM value gets changed then the corresponding property of ViewModel object gets changed automatically. In below example I have Name Text Box and Read only label. If you change the name then the viewModel name property will gets changed and whatever DOM element linked with Name property of ViewModel will get changed automatically. Here we have one Span element that is linked with Name property of
the View Model. Example:


<div>
    Enter Name: <input type="text" data-bind="value:Name" /><br />
    You Have Entered: <span data-bind="text: Name"></span>
</div>

 


<script type="text/javascript">
var viewModel = {
Name: ko.observable("Rupesh")
}
$(function() {
ko.applyBindings(viewModel);
});
</script>

You can see I have used data-bind property in the DOM elements in order to link them all with the same ViewModel property. Similarly if you have array of objects on which the changes happens you want to track then you can use Ko.observableArray(). It is helpful in Result Grid while you show list of data and when you change any row. The ViewModel will get updated automatically with that row.

Combining Multiple Observable Data [ Two way Data Binding ]

You can make another DOM element that will depend on 2 or more observable DOM elements. Let’s have one example. Say you have two Text Boxes like: First Name and Last Name. And now you want to show one read-only Text say Full name that is the concatenation of First Name and Last Name. The Full Name Text should automatically get changed when the user will change First Name and Last Name. If you want to achieve this requirement then you can use “dependentObservable” method. You can write “Ko.dependentObservable(callback, object)” See the below example:


<div>
First Name:
<input type="text" data-bind="value:<span />
Last Name:
<input type="text" data-bind="value:<span />
<br />
Full Name: <span data-bind="text:FullName"></span>

 


<script type="text/javascript">
var viewModel = {
FirstName: ko.observable("Rupesh")
,LastName: ko.observable("Tiwari")
}
viewModel.FullName = ko.dependentObservable(function() {
return this.FirstName() + " " + this.LastName();
}, viewModel);

$(function() {
ko.applyBindings(viewModel);
});

</script>

Updating DOM behavior

There are properties those help on expressing the behavior of DOM Elements. They are many I am listing out few: Visible, Enable, disable, checked.


 </pre>
<div data-bind="visible:<span class=">myBooks().length>0"></div>
<pre>
<pre>
    Show this div if 'myBooks' has at least one Book.

</div>

 


<script type="text/javascript">
var viewModel = {

    myBooks: ko.observableArray([]) // Initially empty, so div is hidden
 };
 viewModel.myBooks.push("jQuery In Action"); // Now visible

$(function() {
ko.applyBindings(viewModel);
});
</script>

Using jQuery Template with KO

We can use jquery template to show list of data like table records. However, if we update any row of the table then in jquery template while rendering the updated row it renders the entire table. In order to overcome this problem knockout came up with foreach helper method that will allow the browser to render those part out of the template modified. Please see the below example: I am adding a new book in my book list and for that I have created one template bookTemplate. On click of Add Book button it only appends the new row in the table using the jquery template. However , while appending the new row it is not rerendering the entire template that is the benefit and performance improvement part.

<p dir="ltr"> <div>
<table>
<thead>
<tr>
<th>
Author Name
</th>
<th>
Book Name
</th>
</tr>
</thead>
<tbody data-bind='template: { name: "bookTemplate",foreach: books }'>
</tbody>
</table>
<button data-bind="click: <span class=">addBook"></button>
Add Book</button>
</div></p>

 


<script type="text/html" id="bookTemplate">
<tr>
<input type="text" data-bind="value: <span class=" />AuthorName"/>
<input type="text" data-bind="value: <span class=" />BookName" />
</tr>
</script>

 


<script type="text/javascript">
var viewModel = {
books: ko.observableArray([
{ AuthorName: "Yehuda Katz", BookName: "jQuery In Action" },
{ AuthorName: "Cody Lindley ", BookName: "jQuery Cookbook" }
]),
addBook: function () {
this.books.push({AuthorName: "Dan Wellman", BookName: "jQuery UI" });
}
};
ko.applyBindings(viewModel);
</script>

Updating ViewModel and DOM Element

Suppose you got some data from server layer using your Model present inside the server layer. And now you want to update the ViewModel and corresponding UI elements linked with the viewModel Properties. In order to update the ViewModel properties, you can use ViewModel properties as a method and pass the new value as an argument and get updated your ViewModel properties with new value. Suppose you want to search a person by name and display the same Name. Below is the steps for the same:

Step 1. Pass UI search Criteria to Server. You can use ko.toJSON() method to convert your viewmodel object to a JSON object. You can also use JSON.stringify() however in IE 8 and above browser. In old browser you have to use json2.js file as a reference and can use the stringify method of JSON. However, in viewmodel object we do have extra javascript code so if we use JSON’s stringify method on ViewModel
object then it does not clean them out that’s why it is suggested to us ko.toJSON() method.

Step 2. Get the JSON form server side which contains Name. You can use $.getJSON method or $.get or $.ajax to get the JSON object.

Step 3. Bind the JSON with the ViewModel You can use viewModel.Name(jsonobject.Name)

Step 4. Update the HTML DOM Element. ko will automatically update the DOM element the moment viewModel will get updated.

<em>Please Try with "Rupesh", "Ritesh", "Rakesh" names.</em>
<br />
Enter Name to Search:
<input type="text" data-bind="value:Name" />
<button id="btnSearch" data-bind="click:Search">
Get Age</button>
<br />
<div data-bind="visible:Age">
&nbsp; Age is:  
</span>
</div>

 


<script type="text/javascript">
var viewModel = {
    Name: ko.observable()
    ,Age:ko.observable()
    ,Search:function(){
        $.getJSON("json.aspx",{name: viewModel.Name()},function(data) {
          viewModel.Age(data); // updating the viewModel after getting data from server.
     });
    }
};
$(function() {
    ko.applyBindings(viewModel);
});
</script>

 


public partial class json : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
JavaScriptSerializer sr = new JavaScriptSerializer();
string s = Request.Params["name"];
List<ViewModel> ps = new List<ViewModel>(){
new ViewModel(){ Age =23, Name ="Rupesh"}
,new ViewModel(){ Age =24, Name ="Ritesh"}
,new ViewModel(){ Age =25, Name ="Rakesh"}
};

Response.ContentEncoding = Encoding.UTF8;
Response.ContentType = "application/json";
var age = (from p in ps where p.Name == s select p.Age).ToArray();
int ageStr = (age.Count() != 0) ? age[0] : 0;
Response.Write(sr.Serialize(ageStr).ToString());
Response.End();

}
}
public class ViewModel
{
public string Name;
public int Age;
}

Using Mapping Plugin

We saw in our previous example that in order to update the viewModel after getting updated data from server. We have to call each property of the viewModel as a method and pass the new value. Like viewModel.property1(new value); viewModel.property2(new value)… and so on. However, if you want to update the entire viewModel in one chunk. Then you can do this by using knockout mapping. This plugin will convert the JavaScript object into an observable object. That means all of the properties of the object will become observable. If any of the property will modified then it will modify the corresponding linked DOM automatically. For downloading the ko.mapping.js  plugin.

Suppose you have below object:


var store  = {

   item : "Shirt"

 , size : [21,22,23,24]

}

Now if you want to convert the data into standard viewModel then you just have to write:


var viewModel = ko.mapping.fromJS(store);

Now, suppose you got new store value from server side as an JSON formate by making $.get or $.ajax call. And you want to update the each and every property of your viewModel then you can do it by writing one line of code only:


ko.mapping.updateFromJS(viewModel, store);

Above line of code will update the viewModel with the latest values of the store. And ko will automatically update the corresponding DOM elements if they are linked up with this viewModel.

Completing the MVVM pattern

In model MVVM design pattern, we have Model, View and ViewModel object. View is the UI layer, Model is the Server side object that saves or retrieves the data by dealing with the Data Access Layer or any other service or third party. View Model is an abstraction over view that gives the binding of data with the DOM elements. It comprises the presentation logic. So here ViewModel is in UI layer only. As you know that MVVM pattern is made for RIA applications like WPF and Silverlight application. To learn more about MVVM pattern please read Josh Smth’s article .

In RIA application, UI layer takes few responsibilities from the server layer and makes the server layer lighter. knowckout.js allows us to write the presentation logic in viewmodel and using ko object.

Reference

For more details please visit knockoutjs. They have great online tutorial to learn knockout features, please visit this also.

Downloads

1) jquery 2) knockout.js 3) jquery template.js 4) json2.js

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s