2015-05-17 15 views
15

Uczę się KnockoutJS, ale nie rozumiem różnicy między używaniem $root i $parent. Proszę zobaczyć this jsfiddle lub poniższy kod:

<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()); 

W powyższym kodzie $root i $parent są zarówno używane w tym samym celu: aby odnieść zewnętrzną zmienną zakresu. Chciałbym tylko wiedzieć, czy jest jakaś różnica między użytecznościami $root i $parent? Jeśli tak, pomóż mi zrozumieć z dobrym przykładem prawidłowego użycia.

+2

Możesz mieć wiele poziomów rodziców/przodków (np. "Foreach" wewnątrz "foreach"). '$ rodzic' jest * bezpośrednim rodzicem *,' $ root' jest * najbardziej zewnętrznym rodzicem *. – DCoder

+4

Dokumentacja nokautów jest całkiem dobra, przeczytaj odpowiednią sekcję: Wiążący kontekst http://knockoutjs.com/documentation/binding-context.html – nemesv

Odpowiedz

30

Różnica jest prosta

  • $root dotyczy Widok modelu stosowanego do DOM z ko.applyBindings;
  • $parent odnosi się do bezpośredniego zakresu zewnętrznego;

albo wizualnie, z $data „s perspektywy:

tree visualization

lub w słowach the relevant documentation:

  • $parent: Jest to obiekt widoku modelu Kontekst nadrzędny, nadrzędny poza obecnym kontekstem.

  • $root: Jest to główny obiekt modelu widoku w kontekście katalogu głównego, tj. Najwyższy kontekst nadrzędny. Zwykle jest to obiekt, który został przekazany do ko.applyBindings. Jest to odpowiednik $parents[$parents.length - 1].

Zobaczysz tylko praktyczne znaczenie, jeśli mają widok modele zagnieżdżone więcej niż jeden poziom, w przeciwnym razie będą one wynosić do tej samej rzeczy.

To korzyścią jest raczej proste do wykazania:

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>

$root jest zawsze taka sama. Model $parent jest inny, w zależności od tego, jak głęboko jesteś zagnieżdżony.

+0

dlaczego ułożyłeś kod w ten sposób ...... mógłbyś użyć foreach loop coz, który jest łatwy do zrozumienia. Nie rozumiem tego '

<- ko szablon: {name: 'osoba', data: mainPerson} ->
$ korzeń $ rodzic $ dane
' – Mou

+0

możesz napisać swój pełny kod i jsfiddle link. – Mou

Powiązane problemy