如何在不引入紧耦合的情况下跨不同的 AMD 模块共享和更新资源(KO observables)?

How to share and update resources (KO observables) across different AMD modules without introducing tight coupling?

我是 JavaScript 新手,我正在尝试创建一个包含三个 AMD 模块的 Web 应用程序 - Parent、ChildA 和 ChildB。 Parent 模块有一个 KO observable,它存储了 parent 的名字。 child 页面都应该能够读取 Parent 的名称。但我不想在 Parent 和 Child 模块之间添加依赖关系。相反,我想将 Parent 的名称存储在全局共享的 object 中,所有三个模块都可以访问它。

目前,这个object存储着Parent名字的值,所有模块都可以访问它。但是每当我对 Parent 的名称进行任何更改时,更改都不会反映在 Child 模块中。只有 Parent 模块可以更改 Parent 的名称,我希望 child 模块与更改后的 Parent 名称同步。

由于 Parent 的名称是 KO observable,我可以将 Parent 依赖项添加到 child 模块并订阅更改。但我试图避免这些模块之间的紧密耦合。

模块之间紧密耦合的代码(我想消除):

Parent.js:

define(['knockout'], function (ko) {
    this.ParentName = ko.observable("Ross");
});

ChildA.js:

define(['knockout', 'Parent'], function (ko, parent) {
    this.AParent = ko.observable();

    parent.ParentName.subscribe(function (newValue) {
        this.AParent(newValue);
    });
});

ChildB.js:

define(['knockout', 'Parent'], function (ko, parent) {
    this.BParent = ko.observable();

    parent.ParentName.subscribe(function (newValue) {
        this.BParent(newValue);
    });
});

具有共享 object 的代码 - 无法更新 child 模块中 object 的值:

SharedObject.js:

define(['knockout', 'jquery', 'lodash'], function (ko, $, _) {
    var sharedObj = {};
    //create a map
    return sharedObj;
});

Parent.js:

define(['knockout', 'SharedObject'], function (ko, so) {
    this.ParentName = ko.observable("Ross");
    so.put('ParentName', this.ParentName);
});

ChildA.js:

define(['knockout', 'SharedObject'], function (ko, so) {
    this.AParent = ko.observable(so.get('ParentName'));
});

ChildB.js:

define(['knockout', 'SharedObject'], function (ko, so) {
    this.BParent = ko.observable(so.get('ParentName'));
});

请建议一种方法来通知 child 模块共享对象中发生的更改。或者有没有其他方法可以消除这些模块之间的紧密耦合?

提前致谢!

这个问题的解决方案可以在link:

中找到

https://technology.amis.nl/2016/02/13/introducing-the-client-side-event-bus-in-oracle-jet-for-decoupled-interactions-across-templates-view-models-and-modules-with-knockout-postbox/

例如

Parent.js

define (['knockout', ‘knockout-postbox’], function (ko) {
    this.name = ko.observable("Ross");
    ko.postbox.publish("parentName", {‘name': this.name()});
});

ChildA.js

define (['knockout', ‘knockout-postbox’], function (ko) {
    this.Aname = ko.observable();
    ko.postbox.subscribe("parentName", function (newValue) {
        this.Aname(newValue.name); //Ross
    });
});

ChildB.js

define (['knockout', ‘knockout-postbox’], function (ko) {
    this.Bname = ko.observable();
    ko.postbox.subscribe("parentName", function (newValue) {
        this.Bname(newValue.name); //Ross
    });
});