如何在UI组件之间共享Knockout JS可观察对象


12

我了解如何使用imports: {}exports: {}共享UI组件属性,例如:

defaults: {
    exports: {
        shouldShowMessage: '${$.component}'
    }
}

它在导出中返回组件名称。

在此处输入图片说明

但是,当我尝试导出可观察到的淘汰赛时,它始终是未定义的:

defaults: {
    exports: {
        shouldShowMessage: '${$.shouldShowMessage}'
    }
}

...

setupKoBindings: function() {
    this.shouldShowMessage = ko.observable('Testing');
}

在此处输入图片说明

作为一种解决方法,我将按照此处的说明创建一个存储模型,但是我更喜欢使用导入和导出。

Answers:


12

导出对象的值必须解析为UiComponent实例的名称和属性,例如以':'分隔checkout.cart.total:title
导出目标名称必须包含UI组件“名称空间”。

在您的示例中,您将值设置为字符串,该字符串解析为作为导出源的UiComponent的属性。检查出口时未定义,因为这不是有效的出口目标。

这是一个有效的示例:

defaults: {
    exportTarget: "foo.bar",
    exportTargetProperty: "showMessage",

    tracks: {
        shouldShowMessage: true
    },

    exports: {
        shouldShowMessage: '${$.exportTarget}:${$.exportTargetProperty}'
    }
}
...

每次值更改时,上述方法会将shouldShowMessage属性的值复制到showMessage具有全名的UiComponent 的属性中foo.bar
请注意,这也不会自动使目标属性成为KO。如果值更改应触发KO来重新渲染访问该属性的DOM节点,则必须明确声明。

顺便说一句,添加shouldShowMessagetracks对象将使其可以自动观察到ko-es5。使用文字ko.observable()也可以。

在上面的示例中,exportTargetexportTargetProperty在中配置defaults。也可以将它们指定为JSON中UiComponent选项的一部分,这通常更有意义,因为这是定义包括UiComponent名称的UiComponent层次结构的地方。

最后,我想指出一点,我个人认为使用值对象将值传递给其他UI组件的解决方案比使用导出或导入更好。以我的经验,在最简单的情况下,保持DOM或UiComponents中的共享状态是通心粉OOP的秘诀。


很好的解释,谢谢@Vinai!如果有时间,我会尝试一下,并将其标记为接受(如果可行)。
本·克鲁克

我在使用时遇到了一些问题tracks,手动订阅可观察变量this.shouldShowMessage.subscribe is not a function在使用时不再起作用this.shouldShowMessage.subscribe(function() { ... }); 。感觉好像我错过了一步,或者tracks没有以相同的方式创建可观察到的东西。
本·克鲁克

没错,这些属性不再是常规的ko可观察值,而只是ES5 getter / setter对。如果您想访问原始的可观察函数,可以注入ko并使用ko.getObservable(this, 'shouldShowMessage').subscribe(function(newValue) { ...});(第一个参数是viewmodel(this),第二个参数是tracked属性的名称。更多信息,请访问:github.com/SteveSanderson/knockout-es5
Vinai

嗯,这很有意义,您是最好的<3
Ben Crook

1
在尝试了进出口之后,仍然失败了,我同意这是意大利面条式的代码,我已经放弃了,我将继续使用手动订阅和存储模型。
本·克鲁克
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.