【问题标题】:What is the difference between $root and $parent?$root 和 $parent 有什么区别?
【发布时间】:2015-07-28 22:39:06
【问题描述】:

我正在学习 KnockoutJS,但我不明白 $root 和 $parent 用法之间的区别。请查看this jsfiddle,或以下代码:

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

在上面的代码中$root 和$parent 都用于同一个目的:引用外部范围变量。我只是想知道$root 和$parent 用法之间有什么区别吗?如果是,请帮助我理解正确用法的好例子。

【问题讨论】:

  • 你可以有多个级别的父母/祖先(例如foreach在foreach中)。 $parent 是 直接父级,$root 是最外层父级。
  • 淘汰文档相当不错,请阅读相关章节:绑定上下文knockoutjs.com/documentation/binding-context.html

标签: knockout.js


【解决方案1】:

它们相似但不同:

  • $root 指的是用ko.applyBindings 应用于DOM 的视图模型;
  • $parent 指直接外部范围;

或者,在视觉上,从$data 的角度来看:

或者,用the relevant documentation的话来说:

  • $parent:这是父上下文中的视图模型对象,即当前上下文之外的对象。

  • $root:这是根上下文中的主视图模型对象,即最顶层的父上下文。它通常是传递给ko.applyBindings 的对象。相当于$parents[$parents.length - 1]。

  • $data:这是当前上下文中的视图模型对象。在根上下文中,$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>

$root 始终相同。 $parent 会有所不同,具体取决于您嵌套的深度。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-07-13
    • 1970-01-01
    • 2020-05-10
    • 1970-01-01
    • 2018-09-17
    • 2018-06-03
    • 1970-01-01
    • 2019-03-06
    相关资源
    最近更新 更多