knockout.js - knockout - ¿Cuál es la diferencia entre $ root y $ parent?
knockout visible (1)
Estoy aprendiendo KnockoutJS, pero no entiendo la diferencia entre el uso de $root y $parent . Consulte este jsfiddle o el siguiente código:
<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());
En el código anterior $root y $parent se usan con el mismo propósito: para referir la variable de ámbito externo. Solo me gustaría saber si hay alguna diferencia entre los usos $root y $parent ? En caso afirmativo, ayúdenme a comprender con un buen ejemplo de uso correcto.
La diferencia es simple:
-
$rootrefiere al modelo de vista aplicado al DOM conko.applyBindings; -
$parentrefiere al alcance externo inmediato;
O, visualmente, desde la perspectiva de $data :
O, en palabras de la documentación relevante :
$parent: este es el objeto de modelo de vista en el contexto principal, el que está inmediatamente fuera del contexto actual.
$root: este es el objeto del modelo de vista principal en el contexto raíz, es decir, el contexto principal superior. Por lo general, es el objeto que se pasó ako.applyBindings. Es equivalente a$parents[$parents.length - 1].
Solo verá una diferencia práctica si tiene modelos de vista anidados en más de un nivel, de lo contrario equivaldrán a lo mismo.
El beneficio es bastante simple de demostrar:
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>
El $root es siempre el mismo. El $parent es diferente, dependiendo de qué tan anidado estés.