After reading about KnockoutJS, I decided to create a simple demo using JSON to communicate with the web server. The application retrieves a Customer
from an ASP.NET MVC Action and sends it to be saved.
The KnockoutJS is a JavaScript Model View ViewModel (MVVM) framework. The View Model object contains properties which values are specified as ko.observable()
. Knockout will automatically update the UI when the view model changes. KnockoutJS has a declarative binding syntax where the HTML view elements are bound with our view model object. Knockout uses the "data-bind
" attribute in the HTML elements for the data binding.
To learn the basics, go to the KnockoutJS site by clicking here.
Pre-requisites
The ASP.NET MVC Controller has the actions to Get and Add a customer.
namespace KnockoutDemo.Controllers
{
public class HomeController : Controller
{
public ActionResult Index()
{
ViewBag.Message = "";
return View();
}
[AcceptVerbs(HttpVerbs.Post)]
public JsonResult Get(int customerID)
{
Customer customer = new Customer {CustomerID = customerID,
FirstName = "John", LastName = "Doe", IsMale = true };
return Json(customer);
}
[HttpPost]
public JsonResult Add(Customer customer)
{
var message = "Customer: " +
customer.FirstName + " " + customer.LastName + " Added.";
message += " IsMale: " + customer.IsMale.ToString();
return Json(message);
}
}
}
The ASP.NET MVC model is the customer
:
public class Customer
{
public int CustomerID { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public bool IsMale { get; set; }
}
The ASP.NET MVC Layout is as follows:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>@ViewBag.Title</title>
<link href="@Url.Content("~/Content/Site.css")"
rel="stylesheet" type="text/css" />
<script src="@Url.Content("~/Scripts/jquery-1.5.1.min.js")"
type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/modernizr-1.7.min.js")"
type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/knockout.js")"
type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/json2.js")"
type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/knockout.validation.js")"
type="text/javascript"></script>
</head>
<body>
<div class="page">
<header>
<div id="title">
<h1>Knockout Demo</h1>
</div>
<div> </div>
</header>
<div> </div>
<div> </div>
<section id="main">
@RenderBody()
</section>
<footer>
</footer>
</div>
</body>
</html>
And finally, the ASP.NET MVC view has the KnockoutJS specifics:
@{
ViewBag.Title = "Add Customer";
}
<h2>
@ViewBag.Message</h2>
<form action="" method="post">
Customer Number: <span data-bind="text: CustomerID"></span>
First Name: <input data-bind="value:
FirstName" style="width: 200px;" type="text" />
Last Name: <input data-bind="value:
LastName" style="width: 200px;" type="text" />
<input data-bind="checked: IsMale"
type="checkbox" />Male
<input data-bind="click: KnockoutDemoNamespace.addCustomer"
type="button" value="Add Customer" />
</form>
<script type="text/javascript">
var KnockoutDemoNamespace = {};
KnockoutDemoNamespace.initViewModel= function(customer) {
var customerViewModel = {
CustomerID: ko.observable(customer.CustomerID),
FirstName: ko.observable(customer.FirstName),
LastName: ko.observable(customer.LastName),
IsMale: ko.observable(customer.IsMale)
};
return customerViewModel;
}
KnockoutDemoNamespace.bindData = function(customer)
{
var viewModel = KnockoutDemoNamespace.initViewModel(customer);
ko.applyBindings(viewModel);
}
KnockoutDemoNamespace.getCustomer = function (customerID) {
$.ajax({
url: "/Home/Get/",
type: 'post',
data: "{'customerID':'1' }",
contentType: 'application/json',
success: function (result) {
KnockoutDemoNamespace.bindData(result);
},
error: function (jqXHR, textStatus, errorThrown) {
var errorMessage = '';
$('#message').html(jqXHR.responseText);
}
});
}
KnockoutDemoNamespace.addCustomer = function () {
$.ajax({
url: "/Home/Add/",
type: 'post',
data: ko.toJSON(this),
contentType: 'application/json',
success: function (result) {
$('#message').html(result);
}
});
}
$(document).ready(function () {
KnockoutDemoNamespace.getCustomer(1);
});
</script>
The KnockoutJS has the following specifics:
The demo performs a data bind with a span, and the input types text, checkbox and button. Note that the "data-bind
" has the html element attribute to be affected and the View Model property associated.
- View Model object:
customerViewModel
- HTML View: The HTML from the page with the KnockoutJS specific attributes for data binding
- View Model activation:
ko.applyBindings(viewModel);