当使用“with”设置上下文时,Knockout $ parent怀疑

时间:2014-09-16 06:45:04

标签: knockout.js

我有这样的3级嵌套模型

WebsiteViewModel => MenuViewModel => MenuEntryViewModel

WebsiteViewModel是根模型。现在在MenuEntryViewModel的html模板中,我使用 "with" 将绑定上下文设置为 MenuEntryViewModel ,如下所示

<div id="contextSetter" data-bind="with: menuViewModel.menuEntryViewModel">
    <div data-bind="event: {'hidden.bs.modal': function() {console.log($parent);}}">
    ...
    </div>
</div

上述事件绑定令人惊讶地记录 WebsiteViewModel 对象而不是 MenuViewModel

因此,如果当前绑定上下文为 menuViewModel.menuEntryViewModel ,则$ parent不指向 menuViewModel ,它指向 WebsiteViewModel (在这种情况下的根模型)。虽然我可以使用解决方法,但我认为$ parent应该指向 MenuViewModel 。有关此行为的任何评论吗?

2 个答案:

答案 0 :(得分:2)

这是设计原因,因为您将with: menuViewModel.menuEntryViewModel链接在一起,这两个项目的父上下文合在一起WebsiteViewModel

检查@Jeroen发布的这些样本:

Your Nested Structure

在此示例中,menuViewModel.menuEntryViewModel的链接显示上下文被视为单个上下文,其中$parentWebsiteViewModel

<强>标记

<div id="contextSetter" data-bind="with: menuViewModel.menuEntryViewModel">
    <div data-bind="click: function() {console.log($parent);}">
        click me to see console.log
    </div>
</div>

<强> JS

var websiteViewModel  = {
    txt: 'website',
    menuViewModel: {
        txt: 'menu',
        menuEntryViewModel: {
            txt: 'entry'
        }
    }
};

ko.applyBindings(websiteViewModel);

在此示例中,您可以将其修改为console.log($parent.menuViewModel),如果您需要访问它的属性,它将导航到您期望的视图模型。

Modified Structure

在此示例中,如果没有链接,则上下文是单个项目,$parent将按预期进行评估。

<强>标记

<div id="contextSetter" data-bind="with: menuViewModel">
    <div data-bind="click: function() {console.log($parent);}">
        top-click-me to see console.log
    </div>
    <div id="subContextSetter" data-bind="with: menuEntryViewModel">
        <div data-bind="click: function() {console.log($parent);}">
            click me to see console.log
        </div>
    </div>
</div>

<强> JS

var websiteViewModel  = {
    txt: 'website',
    menuViewModel: {
        txt: 'menu',
        menuEntryViewModel: {
            txt: 'entry'
        }
    }
};

ko.applyBindings(websiteViewModel);

答案 1 :(得分:1)

基本上以不同的方式阅读$parent变量。基本上with在设置为WebsiteViewModel的上下文中建立新的上下文,MenuViewModel实际上从未设置为上下文,因此缺少它。你可以做以下......

<div data-bind="with: menuViewModel">
  <div id="contextSetter" data-bind="with: menuEntryViewModel">
    <div data-bind="event: {'hidden.bs.modal': function() {console.log($parent);}}">
    ...
    </div>
  </div>
</div>

这会强制menuViewModel显示为您所期望的$parent