Sign In Start Free Trial
Account

Add to playlist

Create a Playlist

Modal Close icon
You need to login to use this feature.
  • Book Overview & Buying MASTERING KNOCKOUTJS
  • Table Of Contents Toc
MASTERING KNOCKOUTJS

MASTERING KNOCKOUTJS

By : Moran
4.7 (6)
close
close
MASTERING KNOCKOUTJS

MASTERING KNOCKOUTJS

4.7 (6)
By: Moran

Overview of this book

If you are an experienced JavaScript developer who is looking for new tools to build web applications and get an understanding of core elements and applications, this is the book for you. A basic knowledge of DOM, JavaScript, and KnockoutJS is assumed.
Table of Contents (11 chapters)
close
close
10
Index

Control flow bindings

So far, we have looked at one-way and two-way bindings that set or sync data with an attribute on an HTML element. There is a different kind of binding that Knockout uses for modifying the DOM by adding or removing nodes. These are the control flow bindings, and they include foreach, if, with, and template.

All of the control flow bindings work by actually removing their content from the DOM and creating an in-memory template from it. This template is used to add and remove the content as necessary.

Control flow bindings (except if) also introduce a binding context hierarchy. Your root binding context is the viewmodel passed to ko.applyBindings. The data-bind attributes have access to properties in the current context. Control flow bindings (other than if) create a child-binding context, meaning that data-bind attributes inside the control flow binding's template have access to the properties of their context and not the root context. Bindings inside a child context have access to special properties to allow them to navigate the context hierarchy. The most commonly used are:

  • $parent: This accesses the binding context of the immediate parent. In this example, group and $parent.group refer to the same property because $parent accesses the context outside of the person:
    <span data-bind="text: group"></span>
    <div data-bind="with: person">
      <span data-bind="text: name"></span>
    <span data-bind="text: $parent.group"></span>
      </div>
  • $parents[n]: This is an array of parent contexts. The $parents[0] array is same as $parent.
  • $root: This is the root viewmodel, the highest context in the hierarchy.
  • $data: This is the current viewmodel, useful inside foreach loops.

    Note

    For a complete list of context properties, see the Knockout documentation for them at http://knockoutjs.com/documentation/binding-context.html.

The if binding

The if binding takes a value or expression to evaluate and only renders the contained template when the value or expression is truthy (in the JavaScript sense). If the expression is falsy, the template is removed from the DOM. When the expression becomes true, the template is recreated and any contained data-bind attributes are reapplied. The if binding does not create a new binding context:

<div data-bind="if: isAdmin">
  <span data-bind="text: user.username"></span>
  <button data-bind="click: deleteUser">Delete</button>
</div>

This div would be empty when isAdmin is false or null. If the value of isAdmin is updated, the binding will re-evaluate and add or remove the template as necessary.

There is also an ifnot binding that just inverts the expression. It's useful if you want to still use a property reference without needing to add a bang and parentheses. The following two lines are equivalent:

<div data-bind="if: !isAdmin()" >
<div data-bind="ifnot: isAdmin">

The parentheses are needed in the first example because it is an expression, not a property name. They are not needed in the second example because it is a simple property reference.

The with binding

The with binding creates a new binding context using the supplied value, which causes bindings inside the bound element to be scoped to the new context. These two snippets are functionally similar:

<div>
  First Name:
<span data-bind="text: selectedPerson().firstName"></span>
  Last Name:
<span data-bind="text: selectedPerson().lastName"></span>
</div>

<div data-bind="with: selectedPerson">
  First Name:
<span data-bind="text: firstName"></span>
  Last Name:
<span data-bind="text: lastName"></span>
</div>

While saving a few keystrokes and keeping your bindings easier to read is nice, the real benefit of the with binding is that it is an implicit if binding. If the value is null or undefined, the content of the HTML element will be removed from the DOM. In the cases where this is possible, it saves you from the need to make null checks for each descendant binding.

The foreach binding

The foreach binding creates an implicit template using the contents of the HTML element and repeats that template for every element in the array.

This viewmodel contains a list of people we need to render:

var viewmodel = {
  people: [{name: 'Tim'}, {name: 'Justin}, {name: 'Mark'}]
}

With this binding, we create an implicit template for the li element:

<ul data-bind="foreach: people">
  <li data-bind="text: name"></li>
</ul>

This binding produces the following HTML:

<ul>
  <li>Tim</li>
  <li>Justin</li>
  <li>Mark</li>
</ul>

The thing to note here is that the li element is binding against name, which is the property of a person. Inside the foreach binding, the binding context is the child element. If you need to refer to the child itself, you can either use $data or supply an alias to the foreach binding.

The $data option is useful when the array only contains primitives that you want to bind against:

var viewmodel = {
  people: ['Tim', 'Justin, 'Mark']
}
...
<ul data-bind="foreach: people">
  <li data-bind="text: $data"></li>
</ul>

The alias option can clean up your code, but it is particularly useful when you have a nested context and want to refer to the parent. Refer to the following code:

<ul data-bind="foreach: { data: categories, as: 'category' }">
    <li>
        <ul data-bind="foreach: { data: items, as: 'item' }">
          <li>
            <span data-bind="text: category.name"></span>:
            <span data-bind="text: item"></span>
          </li>
         </ul>
    </li>
</ul>

This can be achieved with $parent, of course, but it is more legible when using an alias.

CONTINUE READING
83
Tech Concepts
36
Programming languages
73
Tech Tools
Icon Unlimited access to the largest independent learning library in tech of over 8,000 expert-authored tech books and videos.
Icon Innovative learning tools, including AI book assistants, code context explainers, and text-to-speech.
Icon 50+ new titles added per month and exclusive early access to books as they are being written.
MASTERING KNOCKOUTJS
notes
bookmark Notes and Bookmarks search Search in title playlist Add to playlist font-size Font size

Change the font size

margin-width Margin width

Change margin width

day-mode Day/Sepia/Night Modes

Change background colour

Close icon Search
Country selected

Close icon Your notes and bookmarks

Confirmation

Modal Close icon
claim successful

Buy this book with your credits?

Modal Close icon
Are you sure you want to buy this book with one of your credits?
Close
YES, BUY

Submit Your Feedback

Modal Close icon
Modal Close icon
Modal Close icon