Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the difference between $root and $parent?

Tags:

I am learning KnockoutJS, but I do not understand the difference between $root and $parent usage. Please see this jsfiddle, or the below code:

<div data-bind="foreach:mainloop">     $data Value: <span data-bind="text:$data.firstName"></span>                    <span data-bind="text:$data.lastName"></span> --(1)      <br/>     $parent Value: <span data-bind="text:firstName"> </span>                     <span data-bind="text:$parent.lastName"></span>     <br/>     $root Value: <span data-bind="text:firstName"></span>                  <span data-bind="text:$root.lastName"></span>     <br/>         <hr/> </div> 
var mainLoopModel = function () {     var self = this; // Root Level scope     self.mainloop = ko.observableArray([{         'firstName': 'jhon'     }, {         'firstName': 'sam'     }]);     self.lastName = ko.observable('peters');     /*if you remove $data before lastName in note (1) you get undefined error because because mainloop dont have lastName root model has lastName so you have to access using parent or higher level */ }  ko.applyBindings(new mainLoopModel()); 

In the above code $root and $parent are both used for the same purpose: to refer outer scope variable. I just like to know is there any difference between the $root and $parent usages? If yes then please help me understand with a good example for correct usage.

like image 374
Mou Avatar asked May 17 '15 10:05

Mou


People also ask

Is root a parent?

The topmost node in the tree is called the root. Every node (excluding a root) in a tree is connected by a directed edge from exactly one other node. This node is called a parent. On the other hand, each node can be connected to arbitrary number of nodes, called children.

What is $data in knockout?

The $data variable is a built-in variable used to refer to the current object being bound. In the example this is the one of the elements in the viewModel.


1 Answers

They are similar but different:

  • $root refers to the view model applied to the DOM with ko.applyBindings;
  • $parent refers to the immediate outer scope;

Or, visually, from $data's perspective:

tree visualization

Or, in words of the relevant documentation:

  • $parent: This is the view model object in the parent context, the one immeditely outside the current context.

  • $root: This is the main view model object in the root context, i.e., the topmost parent context. It’s usually the object that was passed to ko.applyBindings. It is equivalent to $parents[$parents.length - 1].

  • $data: This is the view model object in the current context. In the root context, $data and $root are equivalent.

You'll only see a practical difference if you have view models nested more than one level, otherwise they will amount to the same thing.

It benefit is rather simple to demonstrate:

var Person = function(name) {    var self = this;    self.name = ko.observable(name);    self.children = ko.observableArray([]);  }      var ViewModel = function() {    var self = this;    self.name = 'root view model';    self.mainPerson = ko.observable();  }    var vm = new ViewModel(),      grandpa = new Person('grandpa'),      daddy = new Person('daddy'),      son1 = new Person('marc'),      son2 = new Person('john');    vm.mainPerson(grandpa);  grandpa.children.push(daddy);  daddy.children.push(son1);  daddy.children.push(son2);    ko.applyBindings(vm);
th, td { padding: 10px; border: 1px solid gray; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>    <script type="text/html" id="person">    <tr>      <td data-bind="text: $root.name"></td>      <td data-bind="text: $parent.name"></td>      <td data-bind="text: $data.name"></td>    </tr>    <!-- ko template: { name: 'person', foreach: children } --><!-- /ko -->  </script>    <table>    <tr>      <th>$root</th>      <th>$parent</th>      <th>$data</th>    </tr>    <!-- ko template: { name: 'person', data: mainPerson } --><!-- /ko -->  </table>

The $root is always the same. The $parent is different, depending on how deeply nested you are.

like image 78
Jeroen Avatar answered Sep 18 '22 00:09

Jeroen