KnockoutJS - Foreach Binding



In this binding, each array item is referenced in HTML markup in a loop. This is very useful while populating a list or table data. foreach can be nested along with other control flow bindings.

Syntax

foreach: <binding-array>

Parameters

  • Array name is passed as a parameter. HTML markup is processed for each item in a loop.

  • A JavaScript object literal can be passed as a parameter and can be iterated over using a property called data.

  • If the parameter is an observable one, then any modifications made are reflected in the UI as soon as the underlying observable changes.

Example

Let us take a look at the following example, which demonstrates the use of foreach binding.

<!DOCTYPE html>
   <head>
      <title>KnockoutJS foreach binding</title>
      <script src = "https://ajax.aspnetcdn.com/ajax/knockout/knockout-3.1.0.js"
         type = "text/javascript"></script>
   </head>
   
   <body>
      <p>List of courses available:</p>
      <div data-bind = "foreach: courseArray ">
         <li data-bind = "text: $data"><span data-bind="text: $index"></span></li>
      </div>

      <script type="text/javascript">
         function AppViewModel() {
            this.courseArray = (['JavaScript','KnockoutJS','BackboneJS','EmberJS']);
            this.courseArray.push('HTML');
         };
         
         var vm = new AppViewModel();
         ko.applyBindings(vm);
      </script>
      
   </body>
</html>

Output

Let's carry out the following steps to see how the above code works −

  • Save the above code in foreach-bind.htm file.

  • Open this HTML file in a browser.

You can rewrite the above code using as keyword. Just change the binding line as shown in the following code.

<div data-bind = "foreach: {data: courseArray, as :'cA' }">

Example

Let's take a look at another example to populate the list details using Observable Array.

<!DOCTYPE html>
   <head>
      <title>KnockoutJS foreach binding</title>
      <script src = "https://ajax.aspnetcdn.com/ajax/knockout/knockout-3.1.0.js"
         type = "text/javascript"></script>
   </head>
   
   <body>
      <p>List of product details:</p>
      <ul data-bind = "foreach: productArray ">
         <li>
            <span data-bind = "text: productName"></span>  
            <a href = "#" data-bind = "click: $parent.removeProduct">Remove </a>
         </li>
      </ul>

      <script type = "text/javascript">
         function AppViewModel() {
            self = this;
            self.productArray = ko.observableArray ([
               {productName: 'Milk'},
               {productName: 'Oil'},
               {productName: 'Shampoo'}
            ]);

            self.removeProduct = function() {
               self.productArray.remove(this);
            }
         };
         
         var vm = new AppViewModel();
         ko.applyBindings(vm);
      </script>
      
   </body>
</html>

Output

Let's carry out the following steps to see how the above code works −

  • Save the above code in foreach-bind-using-observable.htm file.

  • Open this HTML file in a browser.

  • Item from the list is removed dynamically when you click Remove link.

Observations

Utilizing foreach without container

There might be some situation where it is not possible to use the container to include foreach in it. In that situation, container-less format can be used to invoke binding.

<ul>
   <!-- ko foreach: productArray -->
   
   <li>
      <span data-bind="text: productName"></span>
      <a href="#" data-bind="click: $parent.removeProduct">Remove </a>
      <!-- /ko  -->
   </li>
   
</ul>

The <!--ko--> and <!--/ko--> works as start and end markers making it a virtual syntax and binds data as if it is a real container.

Handling destroyed items in array

Array items can be destroyed (made hidden currently and removed later) using destroy array function provided by KO. These items are not shown in foreach and are hidden automatically. To see these hidden items, KO provides a method called includeDestroyed. Hidden items are shown if this parameter is set to Boolean true.

<div data-bind = "foreach: {data: courseArray, includeDestroyed: true  }">
   ...
   ...
   ...
</div>
knockoutjs_declarative_bindings.htm
Advertisements