Ответ 1
Они похожи, но разные:
-
$root
относится к модели представления, примененной к DOM с помощьюko.applyBindings
; -
$parent
ссылается на непосредственную внешнюю область;
Или, визуально, с точки зрения $data
:
Или словами соответствующей документации:
$parent
: это объект модели представления в родительском контексте, тот, который находится вне текущего контекста.
$root
: это объект модели основного представления в корневом контексте, то есть в самом верхнем родительском контексте. Обычно это объект, который был переданko.applyBindings
. Это эквивалентно$parents[$parents.length - 1]
.
$data
: это объект модели представления в текущем контексте. В контексте root $ data и $ root эквивалентны.
Вы увидите практическую разницу только в том случае, если у вас есть модели, вложенные более чем в один уровень, иначе они будут равносильны одному и тому же.
Это преимущество довольно просто продемонстрировать:
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>