typescript - 收集装饰类(没有注册类)

标签 typescript

我有一个事件调度程序类,它应该在某些事件发生时触发监听器。我想通过装饰器注册事件监听器 - 这已经有效,但我对当前的解决方案不是 100% 满意。

目前,事件监听器由全局注册表“收集”,然后在事件调度程序中注册。在代码中,我的(简化的)装饰器看起来像:

// Decorator
export const EventListener = (events: string[]) => {
  return (target: Type<object>): void => {
    EventListenerRegistry.set(target);
  };
};

// Listener example
@EventListener(['start'])
class OnStart {
  public handle() {
  }
}

OnStart 监听器将在 start 事件被调度后立即触发。

我不喜欢这种方法的地方是需要 EventListenerRegistry,它看起来像:

export const EventListenerRegistry = (new class {
    protected listeners = [];

    public set(target) {
        this.listeners.push(target);
    }
});

导入 EventListenerRegistry 意味着在任何时候导入相同的实例,使其非常“单例化”。

我的听众是通过 globrequired - 所以这种方法可以自动将我的听众注册到我的调度程序,而无需做任何额外的工作。

但是除了使用(丑陋的)注册表类之外还有其他可能性吗?

最佳答案

我会使用 IoC 容器。一个不错的 TypeScript 是 Inversify . 这将允许这样的事情:

import { injectable, inject } from 'inversify';

enum EventType {
  Start,
}

interface IEvent {
  type: Event;
  handle(): void;
}

@injectable()
class OnStart implements IEvent {
  public readonly type = EventType.Start;
  public handle() {
  }
}

@injectable()
class Application {
  public constructor(@multiInject(EVENT) public events: IEvent[]) {
  }
}

但这确实意味着您必须自己进行绑定(bind):

export const EVENT = symbol('event');
container.bind<IEvent>(EVENT).to(OnStart);
...

但是,如果您真的想让事件自己自动注册,我想您可以简单地将容器导入装饰器并在那里进行绑定(bind)。

关于typescript - 收集装饰类(没有注册类),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50820746/

相关文章:

javascript - typescript 路径无法解析

javascript - 如何创建一个包含元组的集合,其中每个元组必须是唯一的?

javascript - Ionic 2 typescript 变量总是返回未定义

javascript - 为什么 material-ui 两次调用他们的对话框?

angular - 当变量访问 const 在 Angular/TypeScript 中更新时,const 值发生变化

reactjs - react-router v2.0 的 typescript 定义 - 错误 `has no exported member ' browserHistory'`

angular - NGRX 效果调度了一个无效的 Action

javascript - Angular 2 - 表单数据

typescript - Typescript 中带/不带泛型的条件类型似乎不一致

node.js - 找不到模块 '/app/dist/bin/www.js'