Fundamentals of MVVM
Developers will soon find the MVVM design pattern in Silverlight and WPF necessary. Martin Fowler's Presentation Model, which gathers strength from MVC and MVP flexible structures, serves as the foundation for the MVVM architecture. The UI design patterns with Code-Behind are meant to be entirely or partially distinct from one another.
The three primary components of MVVM are Model, View, and ViewModel. When the View is totally ignorant of the model, ViewModel makes reference to it. This eliminates the developer's need to interact with the business logic interface.
The diagram above describes the situation in the best way. The Model may vary throughout the project. The View is unaware of this situation. The Model is isolated from the View. The ViewModel is a middle man for managing the binding and commands.
With Only jQuery on MVC
Let's talk about jQuery. jQuery has a strong binding mechanism that uses HTML tag ids, a CSS class and a HTML tag name. Values are pushed from the source object into the HTML elements, thus requiring a line of code for each mapping from the source value to the target element. It's much easier with KO. It lets you scale up in complexity without fear of introducing inconsistencies. jQuery is simple to bind with values and tags.
jQuery cannot serve us in the following ways:
Any source object changes will not reflected on HTML elements. (You can push values and call again.)
Any changes in the HTML elements won't be reflected on source objects.
Code:
<h2>Using Jquery
Without Knockout</h2>
<span>StudentNumber:</span><span id="StudentNumber"></span>
<br />
<span>Surname:</span><input id="StudentSurName" />
<span>Name:</span><input id="StudentName" />
<script type="text/javascript">
$(document).ready(function() {
var student = {
Number: "A123456",
Surname: "Leon",
Name: "Alexander"
};
$("#StudentNumber").text(student.Number);
$("#StudentSurName").val(student.Surname);
$("#StudentName").val(student.Name);
});
</script>
You can bind your values to HTML tags using the HTML tag's id and CSS classes. jQuery is an excellent low-level way to manipulate elements and event handlers on a web page. jQuery doesn't have a concept of an underlying data model. If you bind the values of any object like above, you will not observe any changes in the UI after any change of the Model. You must refresh web pages to observe View changes. On the other hand; if you change the HTML element's value then your model won't be fired.
What is knockout.js?
KO is not an alternative to jQuery or other js libraries (Prototype, MooTools). KO focuses on MVVM to manipulate the Model to the View from AJAX calls. KO manages between the ViewModel and View the automatic relation that is triggered by user interface calls.
Model: Business Logic.
View: HTML/CSS. If you change the ViewModel's objects, the View will be effected automatically.
ViewModel: He is a middle man to observable connection Model and View because the Model doesn't have any knowledge of the View.
Observable and Binding: KO's focus is on the Data-Driven js concepts; in other words, any changes in the View will fire the model; also the model's changes will automatically fire the View's updates. KO is on the alert to communicate between them in both directions.
Code:
<h2>With Knockout</h2>
<span>Student Number:</span><span data-bind="text: Number"></span>
<br />
<span>Surname:</span><input data-bind="value: Surname" />
<span>Name:</span><input data-bind="value: Name" />
<script type="text/javascript">
var student = {
Number: "A123456",
Surname: "Leon",
Name: "Alexander"
}
// Activates knockout.js
ko.applyBindings(student);
</script>
The HTML tag binding is unable to observe the Data-Bind structure. KO concentrates on data-binding via the data-bind tag. But the preferred usage is the following. It is useful to control the View's changes for values of the Model's objects. Observable property is one of the most important things. MVVM needs to observe any changes in UI. KO will consider any changes to the View. Actually, when you edit one of those text boxes, it does update the underlying ViewModel data.
Update your ViewModel to make the Name and Surname properties observable using ko.observable:
<script type="text/javascript">
var student = {
Number: ko.observable("A123456"),
Surname: ko.observable("Leon"),
Name: ko.observable("Alexander")
}
// Activates knockout.js
ko.applyBindings(student);
</script>
Now re-run the application and edit the text boxes. This time you'll see not only that the underlying ViewModel data is being updated when you edit, but that all associated UI is updating in sync with it too.
Simple Usage Knockout on MVC
Real-World applications need to be fed from a database. So, the Model would be your application's stored data that would be implemented using a server-side technology. The View is always interested in the UI requests. The Viewmodel contains objects to manage any responses from the View. A programmer must be able to imagine how to generate a ViewModel, not only WPF but also data-driven HTML pages. Data-driven means that the implementation of the ViewModel uses JavaScript.
Sometimes, we don't need to implement the ViewModel with JavaScript. We can bind the server-side Model to the View. "@Html.Raw(Json.Encode(Model));" is an effective way to bind the Server-side Model to the View.
Model: public class Student {
public string Number {
get;
set;
}
public string Name {
get;
set;
}
public string Surname {
get;
set;
}
}
//Controller:
[HttpGet]
publicActionResult StudentMvcWithKnockout() {
Student student = new Student();
student.Number = "B123456";
student.Name = "Peter";
student.Surname = "Scott";
return View(student);
}
//View:
@using System.Web.Script.Serialization;
@model MvcAppWithJquery.Models.Student
@ {
ViewBag.Title = "StudentMvcWithKnockout";
Layout = "~/Views/Shared/_Layout.cshtml";
}
<h2>StudentMvcWithKnockout</h2> <
scriptsrc = "../../Scripts/knockout-2.1.0.js"
type = "text/javascript" > < /script> <
scriptsrc = "../../Scripts/knockout.mapping-latest.js"
type = "text/javascript" > < /script> <
p > Name: < strongdata - bind = "text: Name" > < /strong></p >
<p>SurName:<strongdata-bind="text: Surname"></strong></p> <
scripttype = "text/javascript" >
$(function() {
var model = @Html.Raw(Json.Encode(Model));
ko.applyBindings(model);
}); <
/script>
By calling ko.mapping in the view, we can access JSON data. But we must pass the JSON data from the controller by "return Json(StudentList,JsonRequestBehavior.AllowGet);". So we need a number of collections on ViewModel. We call "ko.applyBindings(viewModel) - so" simply using:
$(document).ready(function () { ko.applyBindings(viewModel); });
The $.ajax and $.getJSON methods are appropriate to get the JSON data. (Controller/Action) You can find two methods in the source code.
Code:
// Controller
public JsonResult GetStudents()
{
List<Student> StudentList = newList<Student>(){new Student(){ Number="A123456", Name="Alexander", Surname="Leon"},
new Student(){ Number="B123456", Name="Peter", Surname="Scott"},
new Student(){ Number="C123456", Name="Michael", Surname="Leroy"},
new Student(){ Number="D123456", Name="Frank", Surname="Mill"}};
return Json(StudentList,JsonRequestBehavior.AllowGet);
}
// View
<tbody data-bind="foreach: Students">
<tr style="border-bottom: 1px solid #000000;">
<td>
<span data-bind="text: Number"></span>
</td>
<td>
<span data-bind="text: Name"></span>
</td>
<td>
<span data-bind="text: Surname"></span>
</td>
</tr>
</tbody>
</table>
</div>
</form>
<script type="text/javascript">
var AppViewModel = function() {
var self = this;
self.Students = ko.mapping.fromJS([]);
$.getJSON('/Student/GetStudents/', function(data) { ko.mapping.fromJS(data, {}, self.Students); });
}
$(document).ready(function() {
var viewModel = new AppViewModel();
ko.applyBindings(viewModel);
});
</script>
Review of Codes
"self.Students = ko.mapping.fromJS([]);" is an important one because "mapping from What?" is necessary. Mapping is controlled by Js. Calling'/Student/GetStudents/' we can feed the ViewModel.
You should use "$.getJSON" and "$.ajax" to get the JSON data.
Using "ko.mapping.fromJS(data, {}, self.Students);" you can fill the "self.Students" ViewModel using data that is in the JSON format.
Summary
KO can help you implement it easier and improve maintainability. Model Changes are observed by the ViewModel and updated UI parts. KO is a simple way to connect the UI from the Data Model. You can charge data procedures on KO so other js events (Click, Mouseover, Grid etc.) can be developed by using jQuery. KO is a pure JavaScript library that works with any server and client-side technology. KO provides a way to use MVVM on MVC technology. KO provides a complimentary, high-level way to link a data model to a UI.