在TypeScript(Angular 2+)中扩展EventTarget?

时间:2018-07-14 20:56:57

标签: angular typescript dom es6-class

有没有一种实际创建类的方法,该类将扩展EventTarget DOM API类?

考虑,我正在上这个课:

class MyClass extends EventTarget {        

  constructor() {
    super();
  }

  private triggerEvent() {
    this.dispatchEvent(new Event('someEvent'));
  }

}

当我尝试实例化它时,出现此错误:

  • ERROR TypeError: Failed to construct 'EventTarget': Please use the 'new' operator, this DOM object constructor cannot be called as a function.

看起来这是由于这样的事实,即该API需要正确的ES2015类才能起作用,但是我正在将代码转换为ES5级别。

如果我使用这样的构造函数:

constructor() {
  Reflect.construct(EventTarget, [], MyClass);
}

尝试在实例上调用addEventListener()时出现以下错误:

  • ERROR TypeError: Illegal invocation

作为副作用,我也收到此TypeScript编译错误:

  • error TS2377: Constructors for derived classes must contain a 'super' call.

1 个答案:

答案 0 :(得分:1)

最简单的解决方案是实际实现EventTarget接口,但将实际实现委托给某些现有类,例如DocumentFragment

此外,我们可以将此功能提取到可重用的类中:

export class DelegatedEventTarget implements EventTarget {

  private delegate = document.createDocumentFragment();


  addEventListener(...args: any): void {
    this.delegate.addEventListener.apply(this.delegate, args);
  }

  dispatchEvent(...args: any): boolean {
    return this.delegate.dispatchEvent.apply(this.delegate, args);
  }

  removeEventListener(...args: any): void {
    return this.delegate.removeEventListener.apply(this.delegate, args);
  }

}

然后,我们可以将其用作初始类的父级:

class MyClass extends DelegatedEventTarget {

  private triggerEvent() {
    this.dispatchEvent(new Event('someEvent'));
  }

}

这将保留输入内容,并且在编译到ES5之前都将保留下来。