如何删除使用"此"的事件监听器?在TypeScript中?

时间:2016-06-25 00:06:21

标签: javascript javascript-events typescript

在JavaScript中,对于需要访问私有成员和函数的事件处理程序,我可以依赖于在我的事件处理函数中可访问的函数范围,并执行以下操作:

theElement.addEventListener("click", onClick);

以后:

theElement.removeEventListener("click", onClick);

在TypeScript中,我需要使用匿名函数让this成为包含对象,如下所示:

theElement.addEventListener("click", (event) => this.onClick(event));

在这种情况下,我无法从侦听事件中删除匿名函数。我如何将一个事件监听器作为一个类的一部分(可以访问私有字段和方法),我可以在以后删除它?

3 个答案:

答案 0 :(得分:19)

首先,即使你这样写,JavaScript和TypeScript的行为也完全相同:

theElement.addEventListener("click", onClick);

其次,这是你可以保留对匿名函数的引用的方法:

var f = (event) => this.onClick(event);
theElement.addEventListener("click", f);
// later
theElement.removeEventListener("click", f);

如果您正在处理事件监听器,那么您的类方法必须有一个有用的模式:

class MyClass {
    init(theElement) {
        theElement.addEventListener("click", this.onClick);
        theElement.addEventListener("click", this.onClick2);
    }
    print() {
        console.log("print");
    }
    onClick() {
        this.print() // possible error (`this` is not guaranteed to be MyClass)
    }

    onClick2 = () => {
        this.print() // no error, `this` is guaranteed to be of type MyClass
    }
}

但请注意,此代码将为类onClick2的每个对象创建单独的函数MyClass。如果您创建了大量MyClass个实例并且很少使用他们的onClick侦听器,那么这会对您的内存使用产生负面影响。

答案 1 :(得分:2)

在打字稿中,很难知道函数调用是什么,尤其是当您“绑定”它时。如:

HTML

from firebase_admin import db ref = db.reference('users') results = ref.order_by_child('name').equal_to(uniqueID).limit_to_first(1).get() firstItem = results.popitem()

和一些创建两个对象的代码

<a id="One"></a>
 <a id="Two"></a>

使用MyClass

let x = new MyClass("I am one", "One");
let y = new MyClass("and I am two", "Two");

单击“一个”元素时将正确显示为“我是一个”,单击第二个元素时,您将正确显示为“并且我为两个”。

这种情况很难移除。您需要添加一个包含绑定的对象变量,以便将我的类更改为:

class MyClass {
    private _myInstance: string;
    constructor(ID: string, domID: string) {
        this._myInstance = ID;
        document.getElementById(domID).addEventListener('click', this.print.bind(this));
    }

    public print() {
        console.log(this._myInstance);
    }
}

}

答案 2 :(得分:0)

已经回答了问题,但是IMO此处针对OOP的答案设计不好。所以,这是我的解决方案:

export class MyClass {

  // create member that holds the function reference
  protected clickEventListener: EventListener;      

  // inject the Element
  constructor(protected theElement: Element) {   
    // wrap the class function `onClick` in an arrow function and assign 
    // to the class member `clickEventListener`   
    this.clickEventListener = () => this.onClick(); 
  }

  onClick() {
    console.log("clicked");
  }

  init() {
    // add the event listener to `theElement` and pass only the reference 
    // of `this.clickEventListener` (no round brackets '()')
    this.theElement.addEventListener("click", this.clickEventListener); 
  }

  destroy() {
    // to remve the event listener also just pass the `clickEventListener` reference
    this.theElement.removeEventListener("click", this.clickEventListener); 
  }

}