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

Posted

技术标签:

【中文标题】如何在不引入紧耦合的情况下跨不同 AMD 模块共享和更新资源(KO observables)?【英文标题】:How to share and update resources (KO observables) across different AMD modules without introducing tight coupling? 【发布时间】:2018-08-31 22:20:47 【问题描述】:

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

目前,该对象存储Parent 名称的值,所有模块都可以访问它。但是,每当我对父名称进行任何更改时,更改都不会反映在子模块中。只有父模块可以更改父模块的名称,我希望子模块与更改的父模块同步。

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

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

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

带有共享对象的代码 - 无法在子模块中更新对象的值:

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

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

提前致谢!

【问题讨论】:

你用的是哪个js框架?我建议将每个子项定义为对父项和对象的任何更新的依赖,您可以通过更新每个子项中的变量来让子项了解它...对于相反的情况,您可以使用pub-sub 排序让父级知道对象已在子级中更新的机制... 我正在使用 Oracle JET。你能解释一下如何添加一个孩子作为对父母的依赖吗? 语法应该与添加子作为对父的依赖的语法相同。 define(['knockout', 'childA', 'childB'], function (ko, childA, childB) this.parentName = "Ross"; childA.parentName = ko.observable(this.name); childB.parentName = ko.observable(this.name); ); @gkb 我想消除模块之间的紧密耦合。我想使用共享对象通知子模块(第二种方法)。 看看这个technology.amis.nl/2016/02/13/… 【参考方案1】:

这个问题的解决方法可以在这个链接中找到:

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/

例如

父.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
    );
);

【讨论】:

以上是关于如何在不引入紧耦合的情况下跨不同 AMD 模块共享和更新资源(KO observables)?的主要内容,如果未能解决你的问题,请参考以下文章

Excel 2010:如何在不修改其输入值的情况下跨多个单元格更改公式?

如何在不启动所有应用程序的情况下跨节点分发应用程序作为分布式握手的一部分

寻找紧耦合设计与 SOA 的支持者

松耦合和紧耦合

如何在保持纵横比且不切断图像数据的情况下跨横向和纵向显示图像

OpenDaylight架构分析