I have created a set of singleton modules which get loaded various knockout components and provide a central "command and control" for their respective functional areas. Let's call them FooModule and BarModule
So a typical Knockout component will have
const ko = require('knockout'),
FooModule =require('../Singletons/FooModel'),
BarModule =require('../Singletons/BarModel');
This seems to work well, with each module supporting various observables and functions
The problem is, I need FooModel to require BarModel, and BarModel to require FooModel.
This probably wouldn't matter if it was not a Singleton (e.g. Class), however I can't have a separate class per module per component or I would lose the ability to communicate across the components (each page typically has 3-7 components, some of which are duplicates but with different data)
Currently FooModel requires BarModel and vice versa, but the resultant object is {}, which presumably how Browserify deals with files that require each other
Currently each singleton module equates to:
FooModel...
const ko = require('knockout');
const BarModel = require('./BarModel');
let hiddenVariable = 42 ;
const FooModel = {
FooMonitor : ko.observable(false),
FooFunction : (variable) => { functionFoo(variable) }
}
const functionFoo = (variable) => {
return variable === hiddenVariable ;
};
module.export FooModel ;
BarModel...
const ko = require('knockout');
const FooModel = require('./FooModel');
let hiddenVariable = 24 ;
const BarModel = {
BarMonitor : ko.observable(false),
BarFunction : (variable) => { functionBar(variable) }
}
const functionBar = (variable) => {
return variable === hiddenVariable ;
};
module.export BarModel ;
Each Knockout component happily requires FooModel & BarModel, but if I add
console.info(BarModel)
In the FooModel Module the browser gets {}
(empty object)
If FooModel
requires BarModel
, BarModel
can't requires FooModel
. It is a module bundler limitation.
Browserify will automatically remove not-used dependencies. That's why the module output is only stripped to {}
when you start using BarModel from FooModel.
Incorporating comments from @spender - when you discover circular dependencies it is time to change the architecture. Events are a good way to decouple the models (in this case, using KO.postbox will work fine).