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

21

我在 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个事件时会变得混乱。我只想让它绑定。 有什么建议吗?
有什么建议吗?
2个回答

21
您可以使用箭头函数作为监听器方法:
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);
}

您还可以检查函数名称并在需要绑定的方法前添加前缀。


3
你还可以缓存控制器上下文。 我在处理d3.js时经常使用这种风格。这样,我仍然可以访问回调的上下文,在d3中通常指DOM元素。
private onClick(): Function {
  controller: this = this;
  return function(event) {
    controller.anotherClassFunction();
  };
}

private secondFunction(): void {
  this.addEventlistener(this.onClick());
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接