TypeScript,如何将类方法事件处理程序上下文保存到“this”实例

问题描述 投票:13回答:2

我在TypeScript中遇到了类的问题。每次我必须要听HTML元素事件时,我需要使用Function.bind()将它连接到当前实例。

class VideoAdProgressTracker extends EventDispatcher
{
    private _video:HTMLVideoElement;

    constructor(video:HTMLVideoElement)
    {
        super();
        this._video = video;
        this._video.addEventListener("timeupdate", this.handleTimeUpdateEvent);
    }

    private handleTimeUpdateEvent(event)
    {
        // Something
    }
}

每次当你有5-10个事件时,我不必保存绑定的匿名函数,它将变得一团糟。我想让它受到约束。

有什么建议?

class events typescript methods listener
2个回答
18
投票

您可以将箭头函数用于侦听器方法:

class VideoAdProgressTracker extends EventDispatcher {
    private _video:HTMLVideoElement;

    constructor(video:HTMLVideoElement) {
        super();
        this._video = video;
        this._video.addEventListener("timeupdate", this.handleTimeUpdateEvent);
    }

    private handleTimeUpdateEvent = (event) => {
        // Something
    }
}

这将正常工作,除非您想扩展此类并覆盖其中一个方法。 这样做的原因是使用箭头函数你实际上没有方法,只有用箭头函数分配的属性,它们不是原型的一部分。

例如:

class A {
    fn1 = () => { }
    fn2() { }
}

编译为:

var A = (function () {
    function A() {
        this.fn1 = function () { };
    }
    A.prototype.fn2 = function () { };
    return A;
}());

因此,如果您不关心能够轻松覆盖其中一种方法,那么请使用此方法。

如果您想继续使用方法但不想手动绑定所有方法,那么您可以:

constructor(video:HTMLVideoElement) {
    super();
    this._video = video;

    for (let key in this) {
        if (typeof this[key] === "function") {
            this[key] = this[key].bind(this);
        }
    }

    this._video.addEventListener("timeupdate", this.handleTimeUpdateEvent);
}

您还可以检查函数名称以及以某种方式绑定您想要绑定的方法。


1
投票

您还可以缓存控制器上下文。在使用d3.js时,我经常使用这种风格。这样我仍然可以访问回调的上下文,在d3中通常指的是一个元素。

private onClick(): Function {
  controller: this = this;
  return function(event) {
    controller.anotherClassFunction();
  };
}

private secondFunction(): void {
  this.addEventlistener(this.onClick());
}
© www.soinside.com 2019 - 2024. All rights reserved.