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:
-
$root
refiere al modelo de vista aplicado al DOM conko.applyBindings
; -
$parent
refiere 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.