1

Playing around with knockout.js, I still don't really get the underlying logic. In the following example, the static javascript array boxList does not have any reference to or by the viewModel, which is in fact totally empty. Still, the foreach binding has no difficulties to grasp the array. Why?


note: obviously, the binding only works when ko.applyBindings has been called, with an empty viewModel as argument.

HTML:

<div data-bind="foreach : boxList">
            <div><input type="checkbox" ><label data-bind="text: name"></label></div>
        </div>

JS:

 var viewModel = {

    };

  var boxList = [
            { name : 'n1'},
            { name : 'n2' },
            { name : 'n3'},
            { name : 'n4' },
        ];


   ko.applyBindings(viewModel);

JSFiddle: http://jsfiddle.net/e85sLmk4/

Lokomotywa
  • 2,624
  • 8
  • 44
  • 73

1 Answers1

1

In case of foreach: boxList the binding expression is a valid Javascript expression, i.e. access to the global variable boxList. Hence Knockout is able to resolve the variable and render the checkboxes for it.

var viewModel = {

 };

 var boxList = [{
   name: 'n1'
 }, {
   name: 'n2'
 }, {
   name: 'n3'
 }, {
   name: 'n4'
 }, ];


 ko.applyBindings(viewModel);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<div data-bind="foreach : boxList">
  <div>
    <input type="checkbox">
    <label data-bind="text: name"></label>
  </div>
</div>

If you had used that binding inside a foreach binding, or with $root or $data contexts, it would be necessary to have those variables under the view model. So a binding expression like foreach : $root.boxList will not work if variable boxList is not declared in the view model.

var viewModel = {

 };

 var boxList = [{
   name: 'n1'
 }, {
   name: 'n2'
 }, {
   name: 'n3'
 }, {
   name: 'n4'
 }, ];


 ko.applyBindings(viewModel);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<div data-bind="foreach : $root.boxList">
  <div>
    <input type="checkbox">
    <label data-bind="text: name"></label>
  </div>
</div>
Nisarg Shah
  • 14,151
  • 6
  • 34
  • 55
  • So I stll don't get what the content of the viewModel object is for. I built an entire app without any properties in the viewModel. – Lokomotywa Oct 10 '17 at 10:25
  • 1
    It is not something special. VM is supposed to be a valid JS object. Some people create it as just an object, some use a constructor to create the object dynamically. Essentially declaring variables and methods inside a view model helps avoid cluttering global namespace. This might be helpful: https://stackoverflow.com/a/9590133/5894241 – Nisarg Shah Oct 10 '17 at 10:45