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.
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.
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.
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:
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 toko.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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With