Knockout.js - is a popular JavaScript library that allows easy creation of feature-rich applications based on Model-View-View Model (MVVM) pattern: user interface can be bound to a separate existing data model. And any change of the model will result in dynamic refresh of the interface.
Introduction
Knockout (KO) is a JavaScript library that helps you to create
rich, responsive display and editor user interfaces with a clean underlying
data model. Any time you have sections of UI that update dynamically (e.g.,
changing depending on the user’s actions or when an external data source
changes), KO can help you implement it more simply and maintainable.
Headline features
Elegant dependency
tracking - automatically updates the right
parts of your UI whenever your data model changes.
Declarative bindings - a simple and obvious way to connect parts of your UI to
your data model. You can construct complex dynamic UIs easily using arbitrarily
nested binding contexts.
Trivially extensible - implement custom behaviors as new declarative bindings
for easy reuse in just a few lines of code.
Additional benefits:
Pure JavaScript
library - works with any server or client-side
technology.
Can be added on top
of your existing web application without requiring major architectural changes.
Compact - around 13kb after zipping.
Works on any
mainstream browser (IE 6+, Firefox 2+,
Chrome, Safari, others)
Comprehensive suite
of specifications (developed
BDD-style) means its correct functioning can easily be verified on new browsers
and platforms.
Knockout MVC is a
library for ASP.NET MVC4 that is a wrapper for Knockout.js that helps to move
entire business logic to the server side: the complete JavaScript code
necessary on the client side will be generated automatically based on the
described C# (or VB.NET) model. Binding of the page interface to business model
is done MVVM-style with the help of C#/VB.NET expressions (not separate
properties, but expressions over them that will be translated to JavaScript
code) using IntelliSense. If complex operations should be done to the model, it
is possible to address to any model method on the server using one short string
(ajax query will be automatically generated; and when the client will get the
updated model, the whole interface will automatically refresh).
Objective
To learn binding of data to the UI using knockoutjs.
Data is returned from the controller and UI will update automatically.
Using the code
UI
Code File
In home controller there are two methods. Index() is
the startup method and return Index view if there is no form key has found. In
case of JSON key it will return JSON data to the UI. GetPerson() method return
model in form of JSON serialized string.
public class HomeController : Controller
{
[AllowAnonymous]
public ActionResult Index()
{
ViewBag.Message = "Sample Application - Knockoutjs with Asp.net MVC4";
string viewKey = string.Empty;
if (Request.Form.AllKeys.Count() > 0)
{
if (Request.Form.AllKeys.Contains("viewName"))
viewKey = Request.Form["viewName"].ToString();
if (viewKey.Equals("JSON"))
return GetPerson();
else
return null;
}
return View();
}
public JsonResult GetPerson()
{
List<Person> persons = new List<Person>
{
new Person(){Name="James", Address="Delhi"},
new Person(){Name="Scott", Address="Bangalore"},
new Person(){Name="Dennish", Address="Australia"},
new Person(){Name="Victor", Address="England"},
new Person(){Name="Adam", Address="Kolkata"},
new Person(){Name="Kate", Address="Delhi"},
new Person(){Name="Christan", Address="Bangalore"},
new Person(){Name="Milanda", Address="Australia"},
new Person(){Name="Thayo", Address="England"},
new Person(){Name="Bjorn", Address="Kolkata"},
};
System.Web.Script.Serialization.JavaScriptSerializer jSearializer = new System.Web.Script.Serialization.JavaScriptSerializer();
string jsonString = jSearializer.Serialize(persons);
return Json(jsonString, JsonRequestBehavior.AllowGet);
}
}
Design
UI include js files of jquery and knockout. Both
files are available in the MVC bundle itself.
Data-bind is a property of knockoutjs to bind data
to the UI. In tbody “persons” is an observable array which contains value for
Name and Address.
Index.cshtml
<script type="text/javascript" src="http://code.jquery.com/jquery-1.9.1.js"></script>
<script type="text/javascript" src="../../Scripts/knockout-2.1.0.js"></script>
@using (Html.BeginForm("Index", "Home", FormMethod.Post, new { @id = "myForm" }))
{
@Html.Hidden("viewName");
<div id="jsonDiv">
<input id="btnGetJSON" type="button" value="Get JSON Data and bind to UI using Knockoutjs" onclick="javascript:GetJSONData('JSON','myForm')" /><br />
<table border="1">
<thead>
<tr>
<th>
Name
</th>
<th>
Address
</th>
</tr>
</thead>
<tbody data-bind="foreach: persons">
<tr>
<td data-bind="text: Name">
</td>
<td data-bind="text: Address">
</td>
</tr>
</tbody>
</table>
</div>
}
<script type="text/javascript" src="../../Scripts/MyScript.js"></script>
MyScript.js is the file where data return from the
controller is bind to the UI.
Function personVM() contain property name bind to
the UI. Object persons is an observable array the getPersons is an internal
method called when data is received from the UI.
In GetJSONData() method an ajax call has been made to
the controller and received JSON data. Now to bind this data to the UI it’s
important to get the context of the div where you have to bind data. After
getting the context object call internal method getPersons() of personVM.
getPersons() method iterate through the received JSON data and insert that data
to the observable array. As the data is getting inserted to the observable
array UI will get updated. That’s how knockoutjs will work.
MyScript.js
function GetJSONData(hiddenValue, formID) {
$("#viewName").val(hiddenValue);
var form = $('#' + formID)
$.ajax({
url: form.attr('action'),
type: "POST",
data: form.serialize(),
success: function (response) {
if (hiddenValue == 'JSON') {
// parseJSON
response = $.parseJSON(response);
//Get div context and Call knockout method
var dn = document.getElementById('jsonDiv');
var x = ko.contextFor(dn);
x.$root.getPersons(response);
}
},
error: function (error) {
alert(error.status + "<--and--> " + error.statusText);
}
});
}
function Person(pname, paddress) {
this.Name = pname;
this.Address = paddress;
}
function personVM() {
var self = this;
self.Name = ko.observable();
self.Address = ko.observable();
self.persons = ko.observableArray([]);
self.getPersons = function (data) {
self.persons.removeAll();
$.each(data, function (key, val) {
self.persons.push(new Person(val.Name, val.Address));
});
};
}
$(document).ready(function () {
var dn = document.getElementById('jsonDiv');
ko.applyBindings(new personVM(), dn);
});
Point to Note
It’s much easier with KO. It lets you scale up in
complexity without fear of introducing inconsistencies. Just represent your
items as a JavaScript array, and then use a foreach binding to transform this
array into a TABLE or set of DIVs. Whenever the array changes, the UI changes
to match (you don’t have to figure out how to inject new TRs or where to inject
them).
Conclusion
Knockoutjs doesn’t compete with jQuery or similar
low-level DOM APIs. Knockoutjs provides a complementary, high-level way to link
a data model to a UI. Knockoutjs itself doesn’t depend on jQuery, but you can
certainly use jQuery at the same time,
Reference
http://knockoutjs.com
http://knockoutmvc.com