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 binding
  2. The text binding
  3. The html binding
  4. The css binding
  5. The style binding
  6. The attr binding

Control flow

  1. The foreach binding
  2. The if binding
  3. The ifnot binding
  4. The with binding
  5. The component binding

Working with form fields

  1. The click binding
  2. The event binding
  3. The submit binding
  4. The enable binding
  5. The disable binding
  6. The value binding
  7. The textInput binding
  8. The hasFocus binding
  9. The checked binding
  10. The options binding
  11. The selectedOptions binding
  12. 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)

Creating custom bindings

You鈥檙e not limited to using the built-in bindings like click, value, and so on 鈥 you can create your own ones. This is how to control how observables interact with DOM elements, and gives you a lot of flexibility to encapsulate sophisticated behaviors in an easy-to-reuse way.

For example, you can create interactive components like grids, tabsets, and so on, in the form of custom bindings (see the grid example).

Registering your binding

To register a binding, add it as a subproperty of ko.bindingHandlers:

ko.bindingHandlers.yourBindingName = {
    init: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
        // This will be called when the binding is first applied to an element
        // Set up any initial state, event handlers, etc. here
    },
    update: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
        // This will be called once when the binding is first applied to an element,
        // and again whenever any observables/computeds that are accessed change
        // Update the DOM element based on the supplied values here.
    }
};

鈥 and then you can use it on any number of DOM elements:

<div data-bind="yourBindingName: someValue"> </div>

Note: you don鈥檛 actually have to provide both init and update callbacks 鈥 you can just provide one or the other if that鈥檚 all you need.

The 鈥渦pdate鈥 callback

Knockout will call the update callback initially when the binding is applied to an element and track any dependencies (observables/computeds) that you access. When any of these dependencies change, the update callback will be called once again. The following parameters are passed to it:

  • element 鈥 The DOM element involved in this binding
  • valueAccessor 鈥 A JavaScript function that you can call to get the current model property that is involved in this binding. Call this without passing any parameters (i.e., call valueAccessor()) to get the current model property value. To easily accept both observable and plain values, call ko.unwrap on the returned value.
  • allBindings 鈥 A JavaScript object that you can use to access all the model values bound to this DOM element. Call allBindings.get('name') to retrieve the value of the name binding (returns undefined if the binding doesn鈥檛 exist); or allBindings.has('name') to determine if the name binding is present for the current element.
  • viewModel 鈥 This parameter is deprecated in Knockout 3.x. Use bindingContext.$data or bindingContext.$rawData to access the view model instead.
  • bindingContext 鈥 An object that holds the binding context available to this element鈥檚 bindings. This object includes special properties including $parent, $parents, and $root that can be used to access data that is bound against ancestors of this context.

For example, you might have been controlling an element鈥檚 visibility using the visible binding, but now you want to go a step further and animate the transition. You want elements to slide into and out of existence according to the value of an observable. You can do this by writing a custom binding that calls jQuery鈥檚 slideUp/slideDown functions:

ko.bindingHandlers.slideVisible = {
    update: function(element, valueAccessor, allBindings) {
        // First get the latest data that we're bound to
        var value = valueAccessor();

        // Next, whether or not the supplied model property is observable, get its current value
        var valueUnwrapped = ko.unwrap(value);

        // Grab some more data from another binding property
        var duration = allBindings.get('slideDuration') || 400; // 400ms is default duration unless otherwise specified

        // Now manipulate the DOM element
        if (valueUnwrapped == true)
            $(element).slideDown(duration); // Make the element visible
        else
            $(element).slideUp(duration);   // Make the element invisible
    }
};

Now you can use this binding as follows:

<div data-bind="slideVisible: giftWrap, slideDuration:600">You have selected the option</div>
<label><input type="checkbox" data-bind="checked: giftWrap" /> Gift wrap</label>

<script type="text/javascript">
    var viewModel = {
        giftWrap: ko.observable(true)
    };
    ko.applyBindings(viewModel);
</script>

Of course, this is a lot of code at first glance, but once you鈥檝e created your custom bindings they can very easily be reused in many places.

The 鈥渋nit鈥 callback

Knockout will call your init function once for each DOM element that you use the binding on. There are two main uses for init:

  • To set any initial state for the DOM element
  • To register any event handlers so that, for example, when the user clicks on or modifies the DOM element, you can change the state of the associated observable

KO will pass exactly the same set of parameters that it passes to the update callback.

Continuing the previous example, you might want slideVisible to set the element to be instantly visible or invisible when the page first appears (without any animated slide), so that the animation only runs when the user changes the model state. You could do that as follows:

ko.bindingHandlers.slideVisible = {
    init: function(element, valueAccessor) {
        var value = ko.unwrap(valueAccessor()); // Get the current value of the current property we're bound to
        $(element).toggle(value); // jQuery will hide/show the element depending on whether "value" or true or false
    },
    update: function(element, valueAccessor, allBindings) {
        // Leave as before
    }
};

This means that if giftWrap was defined with the initial state false (i.e., giftWrap: ko.observable(false)) then the associated DIV would initially be hidden, and then would slide into view when the user later checks the box.

Modifying observables after DOM events

You鈥檝e already seen how to use update so that, when an observable changes, you can update an associated DOM element. But what about events in the other direction? When the user performs some action on a DOM element, you might want to updated an associated observable.

You can use the init callback as a place to register an event handler that will cause changes to the associated observable. For example,

ko.bindingHandlers.hasFocus = {
    init: function(element, valueAccessor) {
        $(element).focus(function() {
            var value = valueAccessor();
            value(true);
        });
        $(element).blur(function() {
            var value = valueAccessor();
            value(false);
        });
    },
    update: function(element, valueAccessor) {
        var value = valueAccessor();
        if (ko.unwrap(value))
            element.focus();
        else
            element.blur();
    }
};

Now you can both read and write the 鈥渇ocusedness鈥 of an element by binding it to an observable:

<p>Name: <input data-bind="hasFocus: editingName" /></p>

<!-- Showing that we can both read and write the focus state -->
<div data-bind="visible: editingName">You're editing the name</div>
<button data-bind="enable: !editingName(), click:function() { editingName(true) }">Edit name</button>

<script type="text/javascript">
    var viewModel = {
        editingName: ko.observable()
    };
    ko.applyBindings(viewModel);
</script>

Note: Supporting virtual elements

If you want a custom binding to be usable with Knockout鈥檚 virtual elements syntax, e.g.:

<!-- ko mybinding: somedata --> ... <!-- /ko -->

鈥 then see the documentation for virtual elements.