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)

The "if" binding

Purpose

The if binding causes a section of markup to appear in your document (and to have its data-bind attributes applied), only if a specified expression evaluates to true (or a true-ish value such as a non-null object or nonempty string).

if plays a similar role to the visible binding. The difference is that, with visible, the contained markup always remains in the DOM and always has its data-bind attributes applied - the visible binding just uses CSS to toggle the container element鈥檚 visiblity. The if binding, however, physically adds or removes the contained markup in your DOM, and only applies bindings to descendants if the expression is true.

Example 1

This example shows that the if binding can dynamically add and remove sections of markup as observable values change.

Here is a message. Astonishing.

Source code: View

<label><input type="checkbox" data-bind="checked: displayMessage" /> Display message</label>

<div data-bind="if: displayMessage">Here is a message. Astonishing.</div>

Source code: View model

ko.applyBindings({
    displayMessage: ko.observable(false)
});

Example 2

In the following example, the <div> element will be empty for 鈥淢ercury鈥, but populated for 鈥淓arth鈥. That鈥檚 because Earth has a non-null capital property, whereas 鈥淢ercury鈥 has null for that property.

<ul data-bind="foreach: planets">
    <li>
        Planet: <b data-bind="text: name"> </b>
        <div data-bind="if: capital">
            Capital: <b data-bind="text: capital.cityName"> </b>
        </div>
    </li>
</ul>


<script>
    ko.applyBindings({
        planets: [
            { name: 'Mercury', capital: null }, 
            { name: 'Earth', capital: { cityName: 'Barnsley' } }        
        ]
    });
</script>

It鈥檚 important to understand that the if binding really is vital to make this code work properly. Without it, there would be an error when trying to evaluate capital.cityName in the context of 鈥淢ercury鈥 where capital is null. In JavaScript, you鈥檙e not allowed to evaluate subproperties of null or undefined values.

Parameters

  • Main parameter

    The expression you wish to evaluate. If it evaluates to true (or a true-ish value), the contained markup will be present in the document, and any data-bind attributes on it will be applied. If your expression evaluates to false, the contained markup will be removed from your document without first applying any bindings to it.

    If your expression involves any observable values, the expression will be re-evaluated whenever any of them change. Correspondingly, the markup within your if block can be added or removed dynamically as the result of the expression changes. data-bind attributes will be applied to a new copy of the contained markup whenever it is re-added.

  • Additional parameters

    • None

Note: Using 鈥渋f鈥 without a container element

Sometimes you may want to control the presence/absence of a section of markup without having any container element that can hold an if binding. For example, you might want to control whether a certain <li> element appears alongside siblings that always appear:

<ul>
    <li>This item always appears</li>
    <li>I want to make this item present/absent dynamically</li>
</ul>

In this case, you can鈥檛 put if on the <ul> (because then it would affect the first <li> too), and you can鈥檛 put any other container around the second <li> (because HTML doesn鈥檛 allow extra containers within <ul>s).

To handle this, you can use the containerless control flow syntax, which is based on comment tags. For example,

<ul>
    <li>This item always appears</li>
    <!-- ko if: someExpressionGoesHere -->
        <li>I want to make this item present/absent dynamically</li>
    <!-- /ko -->
</ul>

The <!-- ko --> and <!-- /ko --> comments act as start/end markers, defining a 鈥渧irtual element鈥 that contains the markup inside. Knockout understands this virtual element syntax and binds as if you had a real container element.

Dependencies

None, other than the core Knockout library.