Getting started

  1. How KO works and what benefits it brings
  2. Downloading and installing

Observables

  1. Creating view models with observables
  2. Working with observable arrays

Computed observables

  1. Using computed observables
  2. Writable computed observables
  3. How dependency tracking works
  4. Pure computed observables
  5. Reference

Bindings

Controlling text and appearance

  1. The visible and hidden bindings
  2. The text binding
  3. The html binding
  4. The class and css bindings
  5. The style binding
  6. The attr binding

Control flow

  1. The foreach binding
  2. The if and ifnot bindings
  3. The with and using bindings
  4. The let binding
  5. The component binding
  6. Binding lifecycle events

Working with form fields

  1. The click binding
  2. The event binding
  3. The submit binding
  4. The enable and disable bindings
  5. The value binding
  6. The textInput binding
  7. The hasFocus binding
  8. The checked binding
  9. The options binding
  10. The selectedOptions binding
  11. The uniqueName binding

Rendering templates

  1. The template binding

Binding syntax

  1. The data-bind syntax
  2. The binding context

Creating custom bindings

  1. Creating custom bindings
  2. Controlling descendant bindings
  3. Supporting virtual elements
  4. Custom disposal logic
  5. Preprocessing: Extending the binding syntax

Components

  1. Overview: What components and custom elements offer
  2. Defining and registering components
  3. The component binding
  4. Using custom elements
  5. Advanced: Custom component loaders

Further techniques

  1. Loading and saving JSON data
  2. Extending observables
  3. Deferred updates
  4. Rate-limiting observables
  5. Unobtrusive event handling
  6. Using fn to add custom functions
  7. Microtasks
  8. Asynchronous error handling

Plugins

  1. The mapping plugin

More information

  1. Browser support
  2. Getting help
  3. Links to tutorials & examples
  4. Usage with AMD using RequireJs (Asynchronous Module Definition)

Asynchronous Module Definition (AMD) With RequireJs

Overview of AMD

Excerpt From Writing Modular JavaScript With AMD, CommonJs & ES Harmony:

When we say an application is modular, we generally mean it’s composed of a set of highly decoupled, distinct pieces of functionality stored in modules. As you probably know, loose coupling facilitates easier maintainability of apps by removing dependencies where possible. When this is implemented efficiently, its quite easy to see how changes to one part of a system may affect another.

Unlike some more traditional programming languages however, the current iteration of JavaScript (ECMA-262) doesn’t provide developers with the means to import such modules of code in a clean, organized manner. It’s one of the concerns with specifications that haven’t required great thought until more recent years where the need for more organized JavaScript applications became apparent.

Instead, developers at present are left to fall back on variations of the module or object literal patterns. With many of these, module scripts are strung together in the DOM with namespaces being described by a single global object where it’s still possible to incur naming collisions in your architecture. There’s also no clean way to handle dependency management without some manual effort or third party tools.

Whilst native solutions to these problems will be arriving in ES Harmony, the good news is that writing modular JavaScript has never been easier and you can start doing it today.

Loading Knockout.js and a ViewModel class via RequireJs

HTML

<html>
    <head>
        <script type="text/javascript" data-main="scripts/init.js" src="scripts/require.js"></script>
    </head>
    <body>
        <p>First name: <input data-bind="value: firstName" /></p>
        <p>First name capitalized: <strong data-bind="text: firstNameCaps"></strong></p>
    </body>
</html>

scripts/init.js

require(['knockout-x.y.z', 'appViewModel', 'domReady!'], function(ko, appViewModel) {
    ko.applyBindings(new appViewModel());
});

scripts/appViewModel.js

// Main viewmodel class
define(['knockout-x.y.z'], function(ko) {
    return function appViewModel() {
        this.firstName = ko.observable('Bert');
        this.firstNameCaps = ko.pureComputed(function() {
            return this.firstName().toUpperCase();
        }, this);
    };
});

Of course, x.y.z should be replaced with the version number of the Knockout script you are loading (e.g., knockout-3.5.1).

Loading Knockout.js, a Binding Handler, and a ViewModel class via RequireJs

Documentation on Binding Handlers in general can be found here. This section is meant to demonstrate the power that AMD modules provide in maintaining your custom handlers. We will take the example of the ko.bindingHandlers.hasFocus example from the binding handlers documentation. By wrapping that handler in it’s own module you can restrict it’s use only to the pages that need it. The wrapped module becomes:

define(['knockout-x.y.z'], function(ko){
    ko.bindingHandlers.hasFocus = {
        init: function(element, valueAccessor) { ... },
        update: function(element, valueAccessor) { ... }
    }
});

After you have defined the module update the input element from the HTML example above to be:

<p>First name: <input data-bind="value: firstName, hasFocus: editingName" /><span data-bind="visible: editingName"> You're editing the name!</span></p>

Include the module in the list of dependencies for your view model:

define(['knockout-x.y.z', 'customBindingHandlers/hasFocus'], function(ko) {
    return function appViewModel(){
        ...
        // Add an editingName observable
        this.editingName = ko.observable();
    };
});

Note that the custom binding handler module does not inject anything into our ViewModel module, that is because it does not return anything. It just appends additional behavior to the knockout module.

RequireJs Download

RequireJs can be downloaded from http://requirejs.org/docs/download.html.