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

时间:2018-03-22 12:58:04

标签: javascript knockout.js requirejs

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

目前,此对象存储Parent的名称值,所有模块都可以访问它。但每当我对Parent的名称进行任何更改时,更改都不会反映在Child模块中。只有Parent模块可以更改Parent的名称,我希望子模块与更改的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中发生的更改。或者还有其他方法可以消除这些模块之间的紧密耦合吗?

提前致谢!

1 个答案:

答案 0 :(得分:0)

可以在此链接中找到此问题的解决方案:

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/

E.g。

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