Kendo MVVM is exciting in UI application development framework that binds a JavaScript model to an HTML view. At the core of the MVVM framework is a JavaScript model definition that defines members of the view model that the view will use. For instance, here is a simplified model:
var vm = kendo.observable({ Name: "" });
The idea here is that the model has a Name property that will be bound. The kendo.observable call wraps the model and prepares it for two-way binding in the UI. In our example, this property can be bound to a control like:
<input type="text" name="Name" data-bind="value:Name" />
Our name property in our view model is bound to the textbox, and the data-bind attribute is responsible for wiring everything up. When the textbox value changes, the view model is updated, and vice versa. This is the main benefit of two-way binding. Taking this and looking at a more complicated example, we can use the same approach within ASP.NET MVC. Below is a sample complex example:
var viewModel = kendo.observable({
ID: null,
ParentItemCategoryTypeID: null,
Code: null,
Name: null,
IsActive: null,
Sequence: null,
categoriesDataSource: new kendo.data.DataSource({
data: @(Html.Raw(JsonConvert.SerializeObject(Model.ItemCategories)))
}),
onClear: function (e) {
this.set("ID", null);
this.set("ParentItemCategoryTypeID", null);
this.set("Code", null);
this.set("Name", null);
this.set("IsActive", false);
this.set("Sequence", null);
},
.
.
});
This view model has 6 properties (ID, Code, Name, etc.); it also has one complex property (a kendo data source that is used to bind to a grid) and an event handler. I’ll come back to the kendo data source later.
At this point, the init method copies the values from the view model (defaulted to null) to input and other HTML elements in the view. In order to link an element to the view model, it requires the data-bind attribute, like the following samples:
<input type="text" class="form-control" data-bind="value:Name" />
Since MVC HTML helpers render out textboxes, we can use TextBox for with the data_ notation. The data_bind attribute renders as data-bind, so we have complete data- attribute support.
@Html.TextBoxFor(i => i.Name, new { @class = "form-control", data_bind = "value:Name" )
Other uses of data-bind attribute can be to wire up click event handlers, bind listviews to kendo data sources, control the visibility of an HTML element, and more.
<button id="ClearFormButton" type="reset" class="btn btn-warning" data-bind="click: onClear">Clear</button>
<tbody id="listview" data-role="listview" data-template="ListItemTemplate" data-selectable="true" data-bind="source:categoriesDataSource, events:{change:onListChange}">
<div data-bind=”visible:showSection”>
The “click” and “events” binding wire up an event handler to a function in the view model, which handles the event. In the event handler, the this pointer refers to the view model, also providing an event argument that gives you access to the underlying control as well. There are many types of other bindings, such as “css”, “visible”, etc. On init, the values from the view model are wired up to each control, and any change within the input control also updates the view model back. The view model has a get/set method to retrieve and use, or update, the view model.
Notice how data-bind for the listview is categoriesDataSource; this is a kendo.data.DataSource object defined on the viewmodel. Interestingly enough, this object takes a URL to a web service or JSON/JavaScript objects. Using Json.NET, the code above (duplicated below) serializes an array into a JavaScript, the following DataSource definition:
categoriesDataSource: new kendo.data.DataSource({
data: @(Html.Raw(JsonConvert.SerializeObject(Model.ItemCategories)))
}),
Is rendered as the following:
categoriesDataSource: new kendo.data.DataSource({
data: [{"ID": 1, "Name": "ABC", ...}]
}),
What ties the view to the model is the kendo.init method:
kendo.init("body", viewModel);
Now our view is bound to our model, and everything is initialized appropriately.