【问题标题】:Knockout nested component using $componentTemplateNodes results in wrong viewModel使用 $componentTemplateNodes 淘汰嵌套组件会导致错误的 viewModel
【发布时间】:2016-08-26 02:54:12
【问题描述】:

我正在尝试从页面视图模型访问嵌套组件的视图模型。

这是模板:

<collapse-panel>
    <custom-component data-bind="viewModel: $root.customComponentVM">
    </custom-component>
</collapse-panel>

折叠面板组件的模板:

<div class="collapse panel-collapse" data-bind="
    template: { nodes: $componentTemplateNodes }">
</div>

在自定义组件中,我使用以下打字稿代码添加了名为 viewModel 的自定义绑定:

ko.bindingHandlers["viewModel"] = {
    init: (element: any,
        valueAccessor: () => KnockoutObservable<any>,
        allBindingsAccessor: KnockoutAllBindingsAccessor,
        viewModel: any,
        bindingContext: KnockoutBindingContext): void => {
        valueAccessor()(viewModel);
    }
};

我的问题是 init 函数中的 viewModel 对象应该是 CustomElementVM,但我得到的是 CollapsePanelVM。

这是我在init方法中添加断点时得到的:

element              //the expected custom-element
viewModel            //the incorrect CollapsePanelVM
ko.dataFor(element)  //also returns the incorrect CollapsePanelVM

我还尝试使用以下语法绑定自定义元素:

<div data-bind="component: {name: 'custom-component' ...

并且还使用 Knockout 注释语法绑定 $componentTemplateNodes:

<div class="collapse panel-collapse">
    <!-- ko template: { nodes: $componentTemplateNodes } --><!-- /ko -->
</div>

但是我仍然得到错误的视图模型。我在这里做错了什么还是这是 Knockout 中的错误? 谢谢。

【问题讨论】:

  • 不应该valueAccessor() 返回您正在寻找的viewModel 吗?敲除通过参数提供的viewModel指的是绑定数据绑定的$data
  • valueAccessor() 返回一个缩小的 js 函数,该函数返回可观察到的淘汰赛。不幸的是,这不是我正在寻找的 viewModel。谢谢

标签: knockout.js


【解决方案1】:

您的绑定处理程序正在collapse-panel 组件的上下文中执行,因为它是内部。标签的上下文适用于其内部,而不适用于标签本身(请注意,例如,if 绑定的工作方式 - 标签始终存在,但其内容可能不存在)。

如果您希望在custom-component 的上下文中执行viewModel 绑定,请在custom-component 模板中的标记上进行该绑定。

如果您希望父级能够设置组件的视图模型,您应该use params

params — 将传递给组件的对象。通常 这是一个包含多个参数的键值对象,并且是 通常由组件的 viewmodel 构造函数接收。

【讨论】:

  • 不幸的是,我无法在自定义组件模板中添加绑定,因为该组件在同一页面中多次使用。他们会互相冲突。有没有办法让foreach: $componentTemplateNodes, as: 'item' 后跟&lt;div data-bind="template: {data: item}"&gt;&lt;/div&gt; 之类的东西将正确的上下文应用于子节点?
  • @skety 在我看来,您想将params 传递给组件。在组件的 viewmodel 构造函数中,您可以使用 params 自定义 vm。这可能会使视图模型绑定处理程序变得不必要。
  • 我想我可以将页面的视图模型传递给一个参数并让组件自己注册到它。你是对的,应该工作。非常感谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-21
  • 1970-01-01
  • 1970-01-01
  • 2012-12-17
  • 2019-07-25
相关资源
最近更新 更多