The $root context always refers to the top-level ViewModel, regardless of loops or other changes in scope. As we saw in the previous lesson, this makes it possible to access top-level methods for manipulating the ViewModel. ### The $data Property

The $data property in a binding context refers to the ViewModel object for the current context. It’s a lot like the this keyword in a JavaScript object. For example, inside of our foreach: shoppingCart loop,$data refers to the current list item. As a result, the following code works exactly as it would without using $data: This might seem like a trivial property, but it’s indispensable when you’re iterating through arrays that contain atomic values like strings or numbers. For example, we can store a list of strings representing tags for each product: Then, define some tags for one of the products in the shoppingCart array: Now, we can see the$data context in action. In the <table> containing our shopping cart items, add a <td> element containing a <ul> list iterating through the tags array:

Inside of the foreach: tags loop, Knockout.js uses the native strings “Baked goods” and “Hot dogs” as the binding context. But, since we want to access the actual strings instead of their properties, we need the $data object. ### The $index Property

Inside of a foreach loop, the $index property contains the current item’s index in the array. Like most things in Knockout.js, the value of$index will update automatically whenever you add or delete an item from the associated observable array. This is a useful property if you need to display the index of each item, like so:

### The $parent Property The $parent property refers to the parent ViewModel object. Typically, you’ll only need this when you’re working with nested loops and you need to access properties in the outer loop. For example, if you need to access the Product instance from the inside of the foreach: tags loop, you could use the \$parent property:

Between observable arrays, the foreach binding, and the binding context properties discussed previously, you should have all the tools you need to leverage arrays in your Knockout.js web applications.

## Discounted Products

Before we move on to the conditional bindings, we’re going to add a discount property to our Product class:

This gives us a condition we can check with Knockout.js’ logical bindings. First, we make the discount parameter optional, giving it a default value of 0. Then, we create an observable for the discount so Knockout.js can track its changes. Finally, we define a computed observable that returns a user-friendly version of the discount percentage.

Let’s go ahead and add a 20% discount to the first item in PersonViewModel.shoppingCart:

## The if and ifnot Bindings

The if binding is a conditional binding. If the parameter you pass evaluates to true, the contained HTML will be displayed, otherwise it’s removed from the DOM. For instance, try adding the following cell to the <table> containing the shopping cart items, right before the “Remove” button.

Everything inside the <td> element will only appear for items that have a discount greater than 0. Plus, since discount is an observable, Knockout.js will automatically re-evaluate the condition whenever it changes. This is just one more way Knockout.js helps you focus on the data driving your application.

Figure 15: Conditionally rendering a discount for each product

You can use any JavaScript expression as the condition: Knockout.js will try to evaluate the string as JavaScript code and use the result to show or hide the element. As you might have guessed, the ifnot binding simply negates the expression.

## The with Binding

The with binding can be used to manually declare the scope of a particular block. Try adding the following snippet towards the top of your view, before the “Checkout” and “Add Beer” buttons:

Inside of the with block, Knockout.js uses PersonViewModel.featuredProduct as the binding context. So, the text: name and text: price bindings work as expected without a reference to their parent object.

Of course, for the previous HTML to work, you’ll need to define a featuredProduct property on PersonViewModel:

## Summary

This lesson presented the foreach, if, ifnot, and with bindings. These control-flow bindings give you complete control over how your ViewModel is displayed in a view.

It’s important to realize the relationship between Knockout.js’ bindings and observables. Technically, the two are entirely independent. As we saw at the very beginning of this series, you can use a normal object with native JavaScript properties (i.e. not observables) as your ViewModel, and Knockout.js will render the view’s bindings correctly. However, Knockout.js will only process the template the first time around—without observables, it can’t automatically update the view when the underlying data changes. Seeing as how this is the whole point of Knockout.js, you’ll typically see bindings refer to observable properties, like our foreach: shoppingCart binding in the previous examples.

Now that we can control the logic behind our view templates, we can move on to controlling the appearance of individual HTML elements. The next lesson digs into the fun part of Knockout.js: appearance bindings.

This lesson represents a chapter from Knockout Succinctly, a free eBook from the team at Syncfusion.