在TypeScript的类内创建自定义事件

时间:2018-08-03 23:17:53

标签: typescript events event-handling

我试图弄清楚如何在TypeScript中为类创建自定义事件。像this one这样的示例在理解如何做方面并没有太大帮助。

我的示例类如下所示。

Cat.ts:

export class Cat {
    public getName(): string {
        return this.catName;
    }

    public setName(catName: string) {
        this.catName = catName;
    }

    constructor(private catName: string) { }

    public makeMeow() {
        this.onWillMeow();
        console.log("Cat meows!");
        this.onDidMeow();
    }

    public onWillMeow() {
        console.log("onWillMeow");
    }

    public onDidMeow() {
        console.log("onDidMeow");
    }
}

现在,我希望能够从外部声明事件,如以下代码旨在演示。

const myCat: Cat = new Cat("Tikki");
myCat.onWillMeow({event => {
     console.log("Tikki the cat is just about to meow!");
}});
myCat.onWillMeow({event => {
     console.log("Tikki the cat did just meow!");
}});
myCat.makeMeow();

现在,我想得到这样的输出:

onWillMeow
Tikki the cat is just about to meow!
Cat meows!
onDidMeow
Tikki the cat did just meow!

我该怎么做才能在TypeScript中工作?究竟如何称呼它?创建 自定义事件 还是创建 自定义事件处理程序

2 个答案:

答案 0 :(得分:5)

类似这样的东西:

type Handler<E> = (event: E) => void;

class EventDispatcher<E> { 
    private handlers: Handler<E>[] = [];
    fire(event: E) { 
        for (let h of this.handlers)
            h(event);
    }
    register(handler: Handler<E>) { 
        this.handlers.push(handler);
    }
}

interface WillMeowEvent { }
interface DidMeowEvent { }

class Cat {
    public getName(): string {
        return this.catName;
    }

    public setName(catName: string) {
        this.catName = catName;
    }

    constructor(private catName: string) { }

    public makeMeow() {
        this.fireWillMeow({});
        console.log("Cat meows!");
        this.fireDidMeow({});
    }

    private willMeowDispatcher = new EventDispatcher<WillMeowEvent>();
    public onWillMeow(handler: Handler<WillMeowEvent>) {
        this.willMeowDispatcher.register(handler);
    }
    private fireWillMeow(event: WillMeowEvent) { 
        console.log("onWillMeow");
        this.willMeowDispatcher.fire(event);
    }

    private didMeowDispatcher = new EventDispatcher<DidMeowEvent>();
    public onDidMeow(handler: Handler<DidMeowEvent>) {
        this.didMeowDispatcher.register(handler);
    }
    private fireDidMeow(event: DidMeowEvent) { 
        console.log("onDidMeow");
        this.didMeowDispatcher.fire(event);
    }
}

const myCat: Cat = new Cat("Tikki");
myCat.onWillMeow(event => {
     console.log("Tikki the cat is just about to meow!");
});
myCat.onDidMeow(event => {
     console.log("Tikki the cat did just meow!");
});
myCat.makeMeow();

我确定有可以帮助您的库。任何人都想在另一个答案中推荐图书馆吗?

答案 1 :(得分:1)

今天实现自定义事件时,必须对事件进行强类型化,即在转换期间推断事件发送的数据类型,以减少代码的出错率,这一点很重要。

今天有几个库可以做到这一点。使用sub-events的方法如下:

LEFT JOIN

由于您发送的事件类型相同,只是消息有所不同,因此通常将其归纳为单个事件。这就是为什么在示例中我将其简化为仅一个事件import {SubEvent} from 'sub-events'; class Cat { // strongly-typed event that expects a string: readonly onMeow: SubEvent<string> = new SubEvent(); constructor(private catName: string) { } public makeMeow(message: string) { this.onMeow.emit(`${this.catName} ${message}`); } } const myCat = new Cat('Tikki'); myCat.onMeow.subscribe(message => { // message is strongly-typed here; console.log(message); //-> Tikki cat is doing something }); myCat.makeMeow('cat is doing something'); // send the event

此外,onMeow几乎是当今的标准方法,它使您可以随时轻松取消订阅,如下所示:

subscribe

当不再需要该事件时,您取消订阅:

const sub = myCat.onMeow.subscribe(message => {
    console.log(message); // message is strongly-typed here;
});