At the end of this article, the reader will understand what MVVM is, why it is useful, and how open source JavaScript frameworks like Knockout can help deliver MVVM applications.
Topics covered in this article:
• What is MVVM
• Benefits of MVVM
• How to implement data binding in a jQuery application using Knockout
What is MVVM?
The Model-View-View Model (MVVM) pattern is a software architectural design pattern. This pattern emerged in 2005 to support the inherent data binding functionality offered by XAML subsystems such as Windows Presentation Foundation (WPF) and Silverlight.
Elements of the Pattern
The three elements or “layers” of the pattern will be described in this section.
Model
The Model encapsulates the domain model, business logic and may include data access.
The domain model represents the client-side application model and may define supporting data structures such as business objects. An example of such structures is a Customer object containing properties such as FirstName, LastName, etc.
Figure 1
Business logic refers to logic concerned with retrieving, validating and ensuring the consistency of application data. This excludes UI-specific logic.
View
The view is the application’s User Interface (UI). It defines the appearance of the UI and its visual elements and controls such as text boxes and buttons. The view may also implement view behavior such as animations and transitions.
Figure 2 – View Example
View Model
The view model is responsible for holding application state, handling presentation logic and exposing application data and operations (commands) to the view such as LoadCustomers and SaveCustomers. It acts as the intermediary between the view and model. The view model retrieves data from the model and exposes it to the view as properties in a form that the view can easily digest.
Figure 3 – View Model
How all of the these Elements Work Together
Basics
This section will explain the basic sequence of steps involved in a typical MVVM application. Please keep in mind that the order and specific operations of production applications will vary based on application complexity and functionality.
Step 1: View Model Retrieves Data from Model
The view model retrieves data from the model or a data service. It then converts the data into a format that the view can easily display. The converted data is stored within structures of the view model and exposed to the view as properties.
Step 2: View Displays Data to End User
The view displays data for end users to interact with via data boundvisual elements. Data binding is a key MVVM concept. It is also a concept that distinguishes the MVVM pattern from similar patterns such as Model View Controller (MVC). This mechanism works by defining a binding (or data subscription) on a UI visual element (such as a text box) that point to a property on the view model such as FirstName. The binding ensures that the data displayed in the text box will always mirror the view model property that it is bound to. This means that if the bound property changes in the view model, the data in the UI will automatically change to reflect the current state.
Step 3: View Exposes Application Operations to End User via Bound Controls
Standard operations such as loading application data and saving application data are exposed to the view by the view model in the form of commands (or methods). The view contains controls such as buttons that bind (point to)to view model commands. For example, a button labeled “Load Customers” on the view is bound to a command (or method) on the view model named LoadCustomers. When the end user clicks the “Load Customers” button, the LoadCustomers method of the view model is invoked which retrieves customer data from the model and sets its “Customers” property. Any visual element in the view that is bound to the Customers property will automatically be hydrated with the freshly retrieved customer data.
Figure 4
The Don’t Look Up Rule
It’s worth noting the “Don’t look up” MVVM rule. This rule points out that none of the elements (Figure 4) are aware of those above them. For example, the model does not hold a reference to or even know about the view model. But the view model is aware of and interacts with the model as it pulls data. The same can be said for the view model who knows nothing about the view while the view interacts with the view model via its properties.
MVVM Benefits
As with other separation patterns such as MVC, MVVM facilitates the separation of concerns. The advantages of separating concerns in the MVVM manner include the facilitation of the following:
Developer/Designer Collaboration without Conflict
Since the UI is void of any non-visual code such as business logic, the team’s designer can confidently work on modifying the code without worrying about breaking the programmer’s code. And the same can be said about the programmer who will not need to touch the UI markup when writing business logic or state-handling code.
Testable Code
Decoupling the view from the view model enables us to write clean unit tests. For example, we can write a unit test for the view model by calling its LoadCustomers method and then interrogating the Customers property. The UI does not need to be unit tested because it does not contain non-visual logic.
Code Maintainability
Testable, decoupled code is easier to maintain. A bug can be found easier if there is only one place to look inspect. Members of the sustaining engineering team will be more confident when modifying code that is properly covered by unit tests.
Binding: The Magic Revealed
It’s quite easy to imagine how the code would look like to set a property or call a data service. But it’s not as easy to imagine how to write code that handles binding. The good news is that we don’t write that code. In classic MVVM subsystems such as WPF or Silverlight, bindingis declared (configured) in XAML, but implemented by the .Net Framework itself.
Below is a snippet of declarative binding XAML used in the sample MVVM WPF application view (Figure 5).
Figure 5 – MVVM WPF View Example
Content="{Binding Path=CustomerCount}"
Height="28"
HorizontalAlignment="Left"
Margin="171,393,0,0"
Name="label2"
VerticalAlignment="Top"
Width="49"
FontSize="16"
Foreground="White"
Grid.Column="1" />
XAML Binding Example
Figure 6 depicts the basic technology stack of a WPF application.
Figure 6 – Technology Stack of a WPF Application
How to Implement MVVM/Binding in an HTML / jQuery Application
In the last section, we looked at the technology stack of an MVVM WPF application. Figure 7 depicts a similar view of the HTML/jQuery application equivalent.
Figure 7
A web page takes the place of a WPF window. The presentation layer is written in HTML\CSS instead of XAML. Modules that handle logic such as view models are written in JavaScript rather than C#. And the runtime is provided by the web browser. Figure 7 depicts an HTML/jQuery equivalent for each element of its WPF counterpart, except for the Bindingfunctionality. This is where Knockout enters our story. Knockout will be discussed in subsequent sections.
Introduction to Knockout
Knockout is an open source JavaScript library that enables MVVM applications by implementing binding. The code snippet below illustrates Knockout’s declarative binding.
Figure 8 – MVVM HTML/jQuery View Example
data-bind="click: loadCustomers"
Knockout Binding Example
Using Knockout in an Application
To use Knockout in an application, three basic steps are required.
Step 1: Reference the Knockout library in the View
The Knockout library can be downloaded from the official Knockout site (http://knockoutjs.com/).
Step 2: Associate the View Model with the View
//
$(document).ready(function () {
// Instantiate the CustomerViewModel model and apply bindings
var customerViewModel = new CustomerViewModel();
ko.applyBindings(customerViewModel);
});
// ]]>
The view model will commonly reside in a separate JavaScript file. The view model is associated with the view by calling the applyBindingsKnockout method.
Step 3: Define Declarative Bindings in the View
Bindings are declared in the visual element markup by using the data-bindattribute. These bindings are associated with view model properties that are known as observables. Observables are properties that will automatically issue notifications whenever their value changes.
function CustomerViewModel() {
var self = this;
// Properties
self.customers = ko.observableArray();
...
Summary
The MVVM separation pattern facilitates code testability, maintainability, and smoother collaboration amongst software development team members. In subsystems such as WPF and Silverlight, the binding aspect of the pattern is handled by the .Net Framework. Open source libraries such as Knockout may be used to enable MVVM HTML/jQuery applications by providing binding functionality.
Software vendors such as Infragistics publish toolsets with rich HTML5 controls including charts, maps, and grids that inherently support Knockout. Additional information regarding these tools can be found at:
http://www.infragistics.com/products/jquery/
Information about using these controls with Knockout can be found at:
http://www.infragistics.com/community/blogs/tags/Knockout/default.aspx
Additional Information
For more information on working with Knockout, please refer to the documentation and tutorials on the Knockout web site:
The working sample WPF and HTML/jQuery applications may be downloaded at: