Как решить циклическую зависимость javascript?
Файл 1:
import b from "b.js"
class A {
constructor(b) {
this.b = b;
}
}
const a = new A(b)
export default a
Файл 2:
import a from "a.js"
class B {
constructor(a) {
this.a = a;
}
}
const b = new B(a)
export default b
Как такое решить? Методы класса A нужны методам класса B и наоборот.
Ответы (2 шт):
Автор решения: UserTest013
→ Ссылка
Судя по комментариях вам нужно использовать два базовых паттерна: фабрику и обозреватель. Описывать паттерны не вижу смысла, их легко можно найти в инете.
В примере ниже, класс А выполняет роль фабрики и также observable. В нем же, для упрощения, я храню массив с обьектами. Класс В является observer, а также может выступать в роли клиента/тригера для фабрики.
Кнопки и event listener добавил просто для удобства, чтобы пример выглядел рабочим.
class A {
products = [];
observers = [];
factory() {
const product = new Product();
this.products.push(product);
document.body.insertAdjacentHTML('beforeend', `<div>
<button class="del" data-id="${product.id}">del product ${product.id}</button>
<button class="client" data-id="${product.id}">subscribe to ${product.id}</button>
</div>`);
return product;
}
delete(id) {
const index = this.products.findIndex((product) => product.id === id);
this.products.splice(index, 1);
this.notify(id);
document.querySelector(`[data-id="${id}"]`).parentElement.remove();
}
get(id) {
return this.products.find((product) => product.id === id);
}
attach(observer) {
this.observers.push(observer);
}
notify(id) {
for (const observer of this.observers) {
observer.update(id);
}
}
}
class B {
subs = [];
constructor(creator) {
this.creator = creator;
this.creator.attach(this);
}
subscribe(id) {
const product = this.creator.get(id);
this.subs.push({
product
});
}
update(id) {
console.log(id);
this.subs = this.subs.filter((sub) => sub.product.id !== id);
}
}
class Product {
id = String(Math.floor(Math.random() * 9999));
}
const creator = new A();
const client = new B(creator);
document.body.addEventListener('click', (event) => {
if (event.target.classList.contains('add')) {
const product = creator.factory();
}
if (event.target.classList.contains('del')) {
creator.delete(event.target.dataset.id);
}
if (event.target.classList.contains('client')) {
client.subscribe(event.target.dataset.id);
}
if (event.target.classList.contains('show-creator')) {
console.log("Creator products", creator.products.map(_ => _.id).join(','));
}
if (event.target.classList.contains('show-client')) {
console.log("Client subs", client.subs.map(_ => _.product.id).join(','));
}
});
<div>
<button class="add">add product</button>
<button class="show-creator">display creator products</button>
<button class="show-client">display client subs</button>
</div>
Автор решения: Lasna1
→ Ссылка
Решил так:
class A {
constructor(b) {
this.b = b;
this.bInstance = null;
}
createB(B) {
if (!this.bInstance) {
this.bInstance = new B()
}
return this.bInstance;
}
}
let a = new A()
let b = a.createB(B)