【问题标题】:How to trigger events on child instances from parent class in javascript?如何在javascript中从父类触发子实例的事件?
【发布时间】:2020-09-21 14:27:00
【问题描述】:

以下是我用来创建自定义事件发射器的代码。

这样所有继承 EventEmitter 类的类都可以发出和监听事件。 目前事件发射只发生在一个方向。

即。从孩子到父母。

(假设child和parent都继承自EventEmitter类)

class EventEmitter {
  listeners = {}
  
  addListener(eventName, fn) {
    this.listeners[eventName] = this.listeners[eventName] || [];
    this.listeners[eventName].push(fn);
    return this;
  }

  on(eventName, fn) {
    return this.addListener(eventName, fn);
  }

  once(eventName, fn) {
    this.listeners[eventName] = this.listeners[eventName] || [];
    const onceWrapper = () => {
      fn();
      this.off(eventName, onceWrapper);
    }
    this.listeners[eventName].push(onceWrapper);
    return this;
  }

  off(eventName, fn) {
    return this.removeListener(eventName, fn);
  }

  removeListener (eventName, fn) {
    let lis = this.listeners[eventName];
    if (!lis) return this;
    for(let i = lis.length; i > 0; i--) {
      if (lis[i] === fn) {
        lis.splice(i,1);
        break;
      }
    }
    return this;
  }

  emit(eventName, ...args) {
    let fns = this.listeners[eventName];
    if (!fns) return false;
    fns.forEach((f) => {
      f(...args);
    });
    return true;
  }

  listenerCount(eventName) {
    let fns = this.listeners[eventName] || [];
    return fns.length;
  }

  rawListeners(eventName) {
    return this.listeners[eventName];
  }
}

所以我的要求是我想在这个 EventEmitter 类中创建一个名为 triggerChild(eventName) 的新方法,这样当我在父类的子实例上触发此事件时,在子类内部设置一个监听器eventName 将自动被触发并运行一些逻辑。

有点像这样

/// parent class

class Parent extends EventEmitter{

constructor() {
this.childinstance = new Child()

this.parentmethod()
}

parentmethod() {
this.childinstance.triggerChild(eventName)
}

}

&在子实例中

/// child instance class

class Child extends EventEmitter{

constructor () {
this.on(eventName, () => do some logic)
}

}

我本可以这样做:

/// parent class

class Parent extends EventEmitter{

constructor() {
this.childinstance = new Child()

this.parentmethod()
}

parentmethod() {
this.childinstance.runAnyChildMethod()
}

}

但这不是我想要的。我想用 EventEmitter 方式来做。

NB 真正的需要是一种从父级触发子实例的事件。

【问题讨论】:

  • 只是代替triggerChild 调用emit (这是您编写的触发事件的方法)并且有效?!
  • 但是,我不明白您为什么需要classes 或继承——也许parentMethod 除外。你的Child 不应该有一个开始监听事件的构造函数,充其量它应该有一个单独的方法来做到这一点。但实际上你应该只写const child = new EventEmitter(); child.on(…);(也许把它打包成一个函数)。
  • 为什么Parent 甚至是EventEmitter?您似乎从未在其上发出事件。或者更一般地说,为什么ParentChild 实例甚至是两个不同的对象?

标签: javascript


【解决方案1】:

也许你正在寻找这样的东西:

const EventEmitter2 = require('eventemitter2');

class Parent extends EventEmitter2{
    constructor() {
        super();
    }
}

class Child extends EventEmitter2{
    constructor(parent, name) {
        super();
        this.listenTo(parent, ['foo', 'bar']);
        this.on('foo', ()=> console.log(`(${name}).foo`));
        this.on('bar', ()=> console.log(`(${name}).bar`));
    }
}

const parent= new Parent();

const child1= new Child(parent, 'child1');
const child2= new Child(parent, 'child2');

parent.emit('foo');
parent.emit('bar');

输出:

(child1).foo
(child2).foo
(child1).bar
(child2).bar

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-04-16
    • 1970-01-01
    • 1970-01-01
    • 2018-10-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-06-26
    相关资源
    最近更新 更多