knockoutjs knockout data knockout.js

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 con ko.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ó a ko.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.