[英]Multiple instances of a class with shared modules
我在运行多个类实例时遇到一些问题,同时使用ES6模块来实现更清晰的项目结构。
我将尝试在下面解释我的问题。 我的真实项目更大,更复杂,但我以此为例。
main.js
import App from './app';
let instance1 = new App,
instance2 = new App;
app.js
import Layer from './layer'
import Element from './element'
class App {
constructor() {
this.layer = new Layer;
this.element = new Element;
}
addLayer() {
this.layer.addLayer();
}
addElement() {
this.element.addElement();
}
}
module.exports = App;
layer.js
class Layer {
constructor() {
this.layers = [];
}
addLayer(name) {
this.layers.push({
name: name
});
}
}
module.exports = Layer;
element.js
class Element {
constructor() {
this.elements = [];
}
addElement(name) {
this.elements.push({
name: name
});
}
}
module.exports = Element;
现在我获得了instance1
和instance2
的唯一实例,包含它自己的层和元素。 当element.js和layer.js想要彼此交谈时,问题就来了。 我不能import Layer from './layer'
,而无需创建一个新的实例,不能够访问从应用程序内的其他位置创建的层内 element.js。
main.js
import App from './app';
let instance1 = new App,
instance2 = new App;
app.js
import layer from './layer'
import element from './element'
class App {
addLayer() {
layer.addLayer();
}
addElement() {
element.addElement();
}
}
module.exports = App;
layer.js
class Layer {
constructor() {
this.layers = [];
}
addLayer(name) {
this.layers.push({
name: name
});
}
}
let layer = new Layer;
module.exports = layer;
element.js
class Element {
constructor() {
this.elements = [];
}
addElement(name) {
this.elements.push({
name: name
});
}
}
let element = new Element;
module.exports = element;
在这种情况下,我可以从elements.js访问图层, 反过来 ,但它们也将在应用程序的两个实例之间共享,这不是我想要的。
这开始是一个单独的app.js ,其中包含所有内容并且工作正常,但随着项目的增长,它变得非常难以维护。 但下面是我想要实现的一个例子。
app.js
class App {
constructor() {
this.layers = [];
this.elements = [];
}
addLayer(name) {
this.layers.push({
name: name
});
}
addElement(name) {
this.elements.push({
name: name
});
}
}
module.exports = App;
有没有办法从这两个世界中获得最佳效果? 我已经为应用程序的每个实例考虑过类似商店的东西,跟踪它自己的图层和元素,但分享它的功能,但我不知道在哪里放置它以及如何在应用程序周围传递引用。
澄清是因为我在评论中得到了问题。 实际上,这是一个更大的项目,有许多不同的模块,它们以很多不同的方式相互交互。 上面的最小版本只是为了这个问题的目的,但是这里有一些额外的部分作为layer.js和element.js之间交互的一个例子。
main.js
instance1.element.get('element1').addToLayer('background');
layer.js
.addLayer(name) {
this.layers.push({
name: name,
elements: [],
add: (element) => {
this.elements.push(element);
}
});
}
element.js
import layer from './layer';
...
.get(name) {
let el;
for(item in this.elements) {
if(item.name == name) {
el = item;
break;
}
}
return el;
}
.addElement(name) {
this.elements.push({
name: name,
addToLayer: (name) => {
let l;
for(item in layer.layers) {
if(item.name == name {
l = item;
break;
}
}
if(l) l.add(this);
}
});
}
在版本1中 , layer.layers
在这里是空的,因为我必须创建它的新实例。 在版本2中 ,它可以正常工作,但App的所有实例将共享相同的layer.layers
。
import Layer from './layer'
import Element from './element'
class App {
constructor() {
this.layer = new Layer(this);
this.element = new Element(this);
}
addLayer() {
this.layer.addLayer();
}
addElement() {
this.element.addElement();
}
}
module.exports = App;
class Layer {
constructor(app) {
this.App = app;
this.layers = [];
}
addLayer(name) {
this.layers.push({
name: name
});
this.App.element.addElement(name); // Element method
}
foo() {
console.log('Hey you!!');
}
}
module.exports = Layer;
class Element {
constructor(app) {
this.App = app;
this.elements = [];
}
addElement(name) {
// ...
this.App.layer.foo(); // I can talk with Layer class
}
}
module.exports = Element;
我在过去几天一直在解决同样的问题,并提出了一种不需要使用类的方法。
我的完整解决方案是一个地图控件,需要为具有多个地图的仪表板实例化。
免责声明; 我自己没有提出这个解决方案,但是使用了代码导师的建议。
main.mjs
import App from './app.mjs';
const instance1 = App();
const instance2 = App();
app.mjs
import Layer from './layer.mjs';
import Element from './element.mjs';
export default () => {
const app = {};
Layer(app);
Element(app);
return app;
}
layer.mjs / element.mjs
export default app => {
app.layers = [];
app.addLayer = name => {
app.layer.push({
name: name
})
}
}
另外,我创建了一个lib.mjs文件,我将其与Webpack捆绑在一起并用作源库文件。 在这里导入实例构造函数'App'并将此函数分配给window对象。
这是一个jsfiddle,我在其中导入捆绑的库并创建两个映射实例。
lib.mjs
import App from './app.mjs';
window.App = App;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.