Chapter 1. Getting Started with KnockoutJS
KnockoutJS is an open source JavaScript library. It was built to allow you to create dynamic and rich web applications. It is built with the Model-View-ViewModel (MVVM) pattern. Knockout makes it really simple to implement a complex user interface that responds to user interactions.
I like Knockout because it is one of the most lightweight JavaScript libraries available today. It also doesn’t try to be an all-in-one framework. It serves a single purpose: data binding your ViewModel to your user interface.
Implementing Knockout involves three distinct things: a view that contains HTML and CSS elements that get data-bound to it, a ViewModel that contains the data to bind to the view, and telling Knockout to perform the data binding to the view with the ViewModel.
The examples in this chapter demonstrate how to create an HTML page with a basic ViewModel. After we review the basic data binding syntax, we will explore the various types of ViewModels that work with the view.
Data Binding Syntax
Data binding is accomplished by adding an HTML attribute called data-bind
to any HTML element that you want Knockout to replace with information from your ViewModel.
Sometimes an HTML tag does not work, so Knockout also allows you to specify data bindings with HTML comments, as shown in Example 1-1.
Example 1-1. Knockout bindings using HTML comments
<!-- ko -->
<!-- /ko -->
Binding through HTML comments is extremely convenient when you want to wrap your binding around a block of HTML code, or you do not want to create an extra HTML object for the sole purpose of housing a data binding.
Data Binding Example
One of the most common things that Knockout is used for is to dynamically display text or HTML based on data contained within a ViewModel.
Example 1-2 shows creating a header that will display the name
property within the ViewModel.
Example 1-2. Data binding text
<!DOCTYPE html>
<html>
<head>
<title>
Data Binding with KnockoutJS</title>
</head>
<body>
<h1>
Hello<span
data-bind=
"text: name"
></span></h1>
<script
type=
'text/javascript'
src=
'js/knockout-3.2.0.js'
></script>
<script>
var
viewModel
=
function
()
{
this
.
name
=
'Steve Kennedy'
;
};
ko
.
applyBindings
(
viewModel
);
</script>
</body>
</html>
When this example is executed in a browser, it outputs Hello Steve Kennedy
inside an h1
tag.
A span
tag is data-bound to the name
property of the ViewModel. This is done by placing text: name
inside the data-bind
HTML attribute.
As mentioned in the introduction to this chapter, implementing Knockout requires three distinct things. The first is the view, which in this example is the HTML that contains the h1
and span
tags that identify the data binding.
The second is the ViewModel, which in this example is the JavaScript variable/function called viewModel
that contains a single variable name.
The third is telling Knockout to perform the data binding of the view and the ViewModel. This is accomplished by calling the ko.applyBindings
function with a ViewModel.
When this function is executed, Knockout processes both the view and the ViewModel. All data bindings in the view are executed and dynamically replaced with the data from the ViewModel.
Knockout does not limit you to a single ViewModel per view. Large projects or classes that are well designed for reusability are common reasons to bind multiple ViewModels to a single view. This is discussed in more detail in Chapter 6.
What Is MVVM
The Model-View-ViewModel (MVVM) design pattern is based largely on the Model-View-Controller (MVC) pattern. In fact, the MV is shared between them. It’s the ViewModel that really separates the two.
MVVM was designed to implement data binding between your ViewModel and your View. This is what KnockoutJS does for us and does very well. It is accomplished using some simple-to-implement HTML attributes and a JavaScript ViewModel as shown in Example 1-2.
The most important thing to remember when you are building ViewModels is that they should be organized to make it easy to represent how your View uses the data. We explore several common scenarios in the upcoming examples.
Creating a ViewModel
A ViewModel can be any type of JavaScript variable. In Example 1-3, let’s start with a simple JavaScript structure that contains a single property called name
.
Example 1-3. Basic ViewModel
var
myFirstViewModel
=
{
name
:
'Steve Kennedy'
};
The previous example is a perfect scenario of a ViewModel that might not correlate 100% to a data model. Frequently, a data model separates the first and last name into two separate fields to make editing the data easier. However, in a view, it makes more sense to concatenate them into a single field for display.
The previous ViewModel is quite basic. ViewModels are not limited to such a simple structure, as the next examples demonstrate.
Object-Oriented ViewModels
Typically, when I create ViewModels, I create simple or complex JavaScript classes that allow me to leverage an object-oriented style of programming (functions, properties, abstraction, etc.).
Object-Oriented Programming with JavaScript
JavaScript is a fully object-oriented programming (OOP) language based on prototyping. It doesn’t contain class statements like C++, C#, or PHP; however, JavaScript functions can be used to simulate the same behavior.
It also offers full support of OOP language features such as namespaces, objects, properties, inheritance, abstraction, etc.
If you are new to JavaScript or object-oriented programming, the Mozilla Developer Network (MDN) offers a great introductory article.
In Example 1-4, I create a ViewModel that is built with some basic object-orientation that will provide more functionality for our view.
Example 1-4. Object-Oriented ViewModel
var
mySecondViewModel
=
function
()
{
var
self
=
this
;
self
.
name
=
'Steve Kennedy'
;
self
.
getName
=
function
()
{
return
self
.
name
;
};
};
In this example, my ViewModel is a JavaScript function that I’ve made to act like a class in OOP. It contains the same name
variable that I created in the previous example, but this time it is encapsulated in my class and acts like a property of it.
I also added a new function called getName
that allows me to access my name
property without calling my class
property directly from elsewhere in my code.
Self = This?
You may be wondering why the first line of my class is var self = this;
. By creating a variable called self
and assigning it the variable this
, it provides me a property in my class that I can use inside methods of my class and easily reference other methods or properties in my class.
Even though the resulting code between Example 1-4 and Example 1-3 look quite different, in fact, they are quite similar. The name
property can be accessed in the exact same way from either example, as shown in Example 1-5.
Example 1-5. Accessing the name property
alert
(
myFirstViewModel
.
name
);
alert
(
mySecondViewModel
.
name
);
// access the property name
alert
(
mySecondViewModel
.
getName
());
// access the function getName
All three of the previous statements will alert name
.
ViewModels with Parameters
In Examples 1-3 and 1-4, the name
property was hardcoded to a value. In many scenarios, data like this would be populated from a different source: a database, the results of an AJAX call, etc.
In Example 1-6, the name will be populated via an input to the ViewModel.
Example 1-6. A ViewModel with a parameter
function
ViewModel
(
name
)
{
var
self
=
this
;
self
.
name
=
name
;
self
.
getName
=
function
()
{
return
self
.
name
;
};
};
var
myThirdViewModel
=
new
ViewModel
(
'Steve Kennedy'
);
In Examples 1-3 and 1-4, the ViewModel class was assigned directly to the variable. This example is slightly different in that a function (acting like a class) called View
Model
is created that accepts the name
property. This class is then instantiated by passing the name into the constructor.
In all future examples, I will continue to use JavaScript classes as they provide a lot more flexibility. However, if a simple JavaScript variable or structure will suffice for your view, do not feel the need to wrap your ViewModel in a class.
Get Knockout.js now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.