Key Takeaways
- KnockoutJS is a JavaScript library that simplifies the creation of rich, desktop-like web UIs. It offers a simple two-way binding mechanism to link a data model to a UI, making synchronization between them easy.
- Knockout uses the Model-View-View Model (MVVM) design pattern, splitting your application into three parts: a model that holds your application’s data, a view that serves as a connector and communication layer between Model and View, and a view that refers to all UI elements in your application.
- KnockoutJS is built on three core concepts: Declarative Bindings, Dependency Tracking, and Templating. Declarative Bindings connect parts of your UI to your data model. Dependency Tracking uses bindings and special variables called ‘observables’ to update all parts associated with a model data when it changes. Templating comes in handy for displaying a rich structure of view model data while keeping your code simple.
- Observables are special JavaScript objects used in KnockoutJS that can notify subscribers about changes and automatically detect dependencies. This allows the view to automatically update whenever the model changes, without having to manually manipulate the DOM.
A Beginners Guide to KnockoutJS: Basics and Observables
Almost everyone dealing with web technologies knows jQuery, or at least has heard about it. Its unmatched simplicity and conciseness makes the lives of millions of web developers all over the world much easier–and that’s fantastic.Unfortunately jQuery is not solution for every problem. As soon as you decide to create some more complex web apps you encounter a problem – there is no easy way to make your UI and data communicate each other dynamically. With the low-level DOM manipulation and events handling provided by jQuery this is fairly hard to achieve. You need a library providing you with more sophisticated way of communication between your UI and the underlying data model.
And here is where Knockout comes in. Knockout is a JavaScript library which helps the creation of rich, desktop-like web UIs. It simplifies user interactions and makes interfaces fully responsive to any data source changes. Knockout provides a simple two-way binding mechanism to link a data model to an UI, thus making synchronization between them a breeze.
Although you will need to use Knockout with jQuery at the same time, in some cases like animated transitions, Knockout itself doesn’t depend on it. Another thing you need to understand is that Knockout doesn’t compete with jQuery – they both do excellent job; each one in its own direction. As you will see if you want to get the most benefits you should use them together.
In this tutorial, we start with the core concepts and capabilities of Knockout. In part two, we’ll go deeper exploring the built-in bindings and how to use them. And in the finale, we’ll go through some advanced features and techniques, such as extended observables and how to create your own custom bindings. Let’s get started!
Basic Concepts
Before we go through the code examples, first you may need to grasp some basic concepts. Knockout implements Model-View-View Model (MVVM) design pattern for JavaScript. In this pattern your application is split into three parts:
A model that holds your application’s data. This can be data entered by users or JSON data fetched from a web server.
A view that serves as a connector and communication layer between Model and View. It holds data and operations for manipulating this data and display it in the UI. Every time when data model is changed corresponded UI parts updates, reflecting these changes. View Model in your application is represented by JavaScript code.
A view that refers to all UI elements in your application. It is a representation of the structure and appearance for given UI. The view is responsible for displaying data and accepting user input. View is represented by HTML/CSS code in your application.
They are three core concepts upon Knockout is built:
1. Declarative Bindings: These allow you to connect parts of your UI to your data model in a simple and convenient way. When use JavaScript directly to manipulates DOM this may cause broken code if you later change the DOM hierarchy or element IDs. With declarative bindings even if you change the DOM all bound pieces stay connected. You can bind data to a DOM by simply including a data-bind attribute to any DOM element.
2. Dependency Tracking: Thankfully to the bindings and special type of variables called observables every time when your model data has changed all parts associated with it automatically being updated. No need to worry about adding event handlers and listeners. All that extra work is performed internally by Knockout and observables, which notify listeners when underlying values have changed.
3. Templating: This comes in handy when your application becomes more complex and you need a way to display a rich structure of view model data, thus keeping your code simple. Knockout has a native, built-in template engine which you can use right away. But if you want, a third-party template engine, like jquery.tmpl or Underscore, also can be used.
Don’t worry if all this theory sounds obscure to you. When we go through the tutorial and the code examples everything will become clearer.
Getting Started
Before we dive into Knockout you need to download and reference the library in your HTML document.
<script type='text/javascript' src='knockout-2.0.0.js'></script>
To keep your code separate from your presentation is better to create a JavaScript file to hold all application code. And because we will use jQuery in some cases you need to reference it too.
<script type='text/javascript' src='jquery-1.7.1.min.js'></script>
<script type='text/javascript' src='knockout-2.0.0.js'></script>
<script type='text/javascript' src='application.js'></script>
This is considered as best practice but for training purpose and to make things easier you can put the JavaScript code in the same document by either including it in the head tag or place it bellow your markup.
Now, to create a view model just declare any JavaScript object like this:
function viewModel() {
// Your code here
};
The data-bind attribute (explained later) isn’t native to HTML, and the browser doesn’t know what it means. So in order to take effect Knockout has to be activated by inserting ko.applyBindings()
function at the end of the script. Also if you use external JavaScript file or your script is placed in the head tag of your document you need to wrap the Knockout code in a jQuery ready function in order to work properly. Here is the basic template to start:
$(document).ready(function(){
function viewModel() {
// Your code here
};
ko.applyBindings(new viewModel());
});
Calling the ko.applyBindings()
method and passing in our view model tells Knockout to bind the specified model to our UI. You can even provide a DOM element if you only want to bind this view model to one part of your overall UI. ko.applyBindings()
takes two parameters. The first parameter says what view model object you want to use with the declarative bindings it activates. The second parameter is optional and it defines which part of the document you want to search for data-bind attributes. For example, ko.applyBindings(viewModel, document.getElementById('container'))
will restrict the activation to the element with ID container and its descendants. This is useful if you want to have multiple view models and associate each with a different region of the page.
How It Works
With Knockout, you can bind data to a DOM element by including a data-bind attribute in the markup which specifies the data-binding to perform. The code never has any reference to the DOM structure so you can freely change the HTML without breaking your bindings. In the following example we add text data-bind attribute to span
element like this:
// syntax: data-bind="bindingName: bindingValue"
<p>The day of the week is <span data-bind="text: dayOfWeek"></span>. It's time for <span data-bind="text: activity"></span></p>
Then if we want to make the value of text to updates dynamically then we have to declare it in our view model as an observable.
function viewModel() { this.dayOfWeek = ko.observable('Sunday'); this.activity = ko.observable('rest'); }; ko.applyBindings(new viewModel());
This will output “The day of the week is Sunday. It’s time for rest”.
Observables
Knockout implements observable properties by wrapping object properties with a custom function named ko.observable()
.
this.property = ko.observable('value')
Observables are set as functions. As such you can use them in the following manner:
// To read the observable's current value, just call the observable with no parameters.
// The following will return Sunday
this.dayOfWeek()
// To write a new value to the observable, call the observable and pass the new value as a parameter.
// The following will change the day of week to Monday
this.dayOfWeek('Monday')
// To write values to multiple observable properties on a model object, you can use chaining syntax.
this.dayOfWeek('Monday').activity('work')
Knockout doesn’t require you to use observable properties. If you want DOM elements to receive values once but then not be updated when the values in the source object change, simple objects will be sufficient. However, if you want your source object and target DOM elements to stay in sync – two-way binding – then you’ll want to consider using observable properties.
In some cases you may need to combine the values of two or more observables into one new value. This can be done with so-called computed observables. Computed observables are functions that are dependent on one or more other observables, and will automatically update whenever any of these dependencies change. The computed property automatically updates when any of the observables it depends on for its evaluation change. In the following example the computed observable named fullDate
will updates every time when one or more of the day
, month
and year
observables change.
<p>Day: <input data-bind="value: day" /></p>
<p>Month: <input data-bind="value: month" /></p>
<p>Year: <input data-bind="value: year" /></p>
<p>The current date is <span data-bind="text: fullDate"></span></p>
function viewModel() {
this.day = ko.observable('24');
this.month = ko.observable('02');
this.year = ko.observable('2012');
this.fullDate = ko.computed(function() {
return this.day() + "/" + this.month() + "/" + this.year();
},this);
};
ko.applyBindings(new viewModel());
The ko.computed()
takes a second parameter this
. Without passing it in, it would not have been possible to refer to this.day()
, this.month()
or this.year()
. In order to simplify things you can create a variable self
, thus avoiding the addition of the second parameter. From now on we will use this approach in the code examples.
function viewModel() {
var self = this;
self.day = ko.observable('24');
self.month = ko.observable('02');
self.year = ko.observable('2012');
self.fullDate = ko.computed(function() {
return self.day() + "/" + self.month() + "/" + self.year();
});
};
ko.applyBindings(new viewModel());
When you dealing with one object you can easily track any changes to it by turn it into an observable. But what if you have multiple objects? In such cases Knockout has a special object called ko.observableArray()
, which can detect and respond to changes of a collection of things. This makes possible to display and/or edit multiple values, for example, when you need repeated sections of UI to appear and disappear as items are added and removed.
You should bear in mind that an observable array tracks which objects are in the array, not the state of those objects. Simply putting an object into an observable array doesn’t make all of that object’s properties themselves observable. If you wish you can make those properties observable, but that’s totally up to you. An observable array just tracks which objects it holds, and notifies listeners when objects are added or removed.
this.property = ko.observableArray();
When you create an observable array you can leave it empty or populate it with some initial values. In the following example we create an observable array populated with the days of the week:
<p>Today is <span data-bind="text: daysOfWeek()[0]"></span></p>
function viewModel() {
var self = this;
self.daysOfWeek = ko.observableArray([
'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'
]);
alert("The week has " + self.daysOfWeek().length + " days");
};
ko.applyBindings(new viewModel());
As you can see, to read and write Knockout array you can use any native JavaScript functions. But Knockout has its own equivalent functions which syntax is a little bit more convenient:
array().push('Some value'); // native JavaScript
array.push('Some value'); // Knockout
For the full list of available functions you can check out the documentation.
If you enjoyed reading this post, you’ll love Learnable; the place to learn fresh skills and techniques from the masters. Members get instant access to all of SitePoint’s ebooks and interactive online courses, like JavaScript Programming for the Web.Frequently Asked Questions (FAQs) about KnockoutJS
What is the difference between KnockoutJS and other JavaScript libraries?
KnockoutJS is a JavaScript library that helps developers to create rich, responsive display and editor user interfaces with a clean underlying data model. Unlike other JavaScript libraries, KnockoutJS uses a Model-View-ViewModel (MVVM) design pattern where the model refers to the data, the view is the visual representation of the data, and the ViewModel is the intermediary between the model and the view. This pattern allows for a clear separation of concerns, making your code easier to manage and test.
How do I get started with KnockoutJS?
To get started with KnockoutJS, you need to include the KnockoutJS library in your HTML file. You can download it from the official KnockoutJS website or include it directly from a Content Delivery Network (CDN). Once you’ve included the library, you can start creating your ViewModel and binding it to your view using the KnockoutJS syntax.
How does data binding work in KnockoutJS?
Data binding in KnockoutJS is a way of establishing a connection between the model (your data) and the view (the DOM elements in your web page). This connection allows changes in your data to automatically update the view, and vice versa. KnockoutJS provides several built-in bindings for common tasks such as text and value binding, and you can also create custom bindings for more complex scenarios.
What are observables in KnockoutJS?
Observables are special JavaScript objects that can notify subscribers about changes, and automatically detect dependencies. In KnockoutJS, you use observables to automatically update the view whenever the model changes, without having to manually manipulate the DOM. This makes your code cleaner and easier to maintain.
How do I use computed observables in KnockoutJS?
Computed observables are functions that are dependent on one or more other observables, and will automatically update whenever any of these dependencies change. To create a computed observable in KnockoutJS, you use the ko.computed function, passing in a function that returns the computed value.
How do I handle events in KnockoutJS?
KnockoutJS provides the event binding to allow you to respond to user actions like clicks or key presses. In your ViewModel, you define a function to handle the event, and then use the event binding in your view to connect the event to your function.
What is the role of the ViewModel in KnockoutJS?
The ViewModel in KnockoutJS is a JavaScript object that represents the data and operations on a UI. It’s responsible for maintaining the state of the view, handling user actions, and updating the model when necessary. The ViewModel is not a direct representation of the data, but rather a specialized version of it for the view.
How do I use templates in KnockoutJS?
Templates in KnockoutJS allow you to define reusable chunks of markup that can be rendered with different data. You can define a template using a script element with the type “text/html”, and then use the template binding to render the template with your data.
How do I debug KnockoutJS applications?
Debugging KnockoutJS applications can be done using the browser’s developer tools. You can inspect the data bound to a DOM element using the ko.dataFor and ko.contextFor functions. Additionally, KnockoutJS provides the ko.toJSON function, which can be used to convert your ViewModel into a JSON string for easy inspection.
Can I use KnockoutJS with other JavaScript libraries?
Yes, KnockoutJS can be used alongside other JavaScript libraries like jQuery or Bootstrap. KnockoutJS does not manipulate the DOM directly, but rather updates the view based on changes to the ViewModel, so it does not interfere with other libraries that manipulate the DOM.
I am a web developer/designer from Bulgaria. My favorite web technologies include SVG, HTML, CSS, Tailwind, JavaScript, Node, Vue, and React. When I'm not programming the Web, I love to program my own reality ;)