Introduction
This article can
be separated into four important parts:
- Fundamentals of Model, View, and ViewModel (MVVM)
- With the Only jQuery on MVC
- Short introduction: Knockout.js
- Simple Usage Knockout on MVC
Fundamentals of MVVM
The MVVM design
pattern in Silverlight / WPF is on the way to becoming indispensable for
developers. The basics of the MVVM architecture is based on Martin Fowler's
Presentation Model that collects power MVC and MVP flexible structure.
The purpose of the UI design patterns with Code-Behind is to separate each other
completely or partially.
MVVM consists of three main things: Model, View, and ViewModel. ViewModel references the Model
when the View is completely unaware of the model. In this way, the developer is not facing to face the business logic interface in any way.
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: "Karatoprak",
- Name: "Yusuf"
- };
- $("#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.
Short Introduction: knockout.js
- 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: "Karatoprak",
- Name: "Yusuf"
- }
-
- 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("Karatoprak"),
- Name: ko.observable("Yusuf")
- }
-
- 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;
- }
- }
-
-
- [HttpGet]
- publicActionResult StudentMvcWithKnockout() {
- Student student = new Student();
- student.Number = "B123456";
- student.Name = "Mahesh";
- student.Surname = "Chand";
- return View(student);
- }
-
-
- @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>
Result
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.
-
- public JsonResult GetStudents()
- {
- List<Student> StudentList = newList<Student>(){new Student(){ Number="A123456", Name="Yusuf", Surname="Karatoprak"},
- new Student(){ Number="B123456", Name="Mahesh", Surname="Chand"},
- new Student(){ Number="C123456", Name="Ä°brahim", Surname="Ersoy"},
- new Student(){ Number="D123456", Name="Mike", Surname="Gold"}};
- return Json(StudentList,JsonRequestBehavior.AllowGet);
- }
-
- <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>
Result
- "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.
References: