在构造函数之外的 Angular 2 中添加和删除文档侦听器



我有一个弹出组件,其模板是可移动的。 调用 open() 方法并附加可移动侦听器时,弹出窗口将打开;然后在调用 close() 方法但侦听器未删除时关闭。 这些是在类级别:

@Output()
open() {
    const div = this.someDiv.nativeElement;
    div.addEventListener('mousedown', this.move.mouseDown.bind(this), false);
    div.addEventListener('touchstart', this.move.touchStart.bind(this), false);
    document.addEventListener('mousemove', this.move.mouseMove.bind(this), false);
    document.addEventListener('touchmove', this.move.touchMove.bind(this), false);
    document.addEventListener('mouseup', this.move.mouseUp.bind(this), false);
    document.addEventListener('touchEnd', this.move.touchEnd.bind(this), false);
    this.display = 'block';
}
@Output()
close() {
    const div = this.someDiv.nativeElement;
    div.removeEventListener('mousedown', this.move.mouseDown.bind(this), false);
    div.removeEventListener('touchstart', this.move.touchStart.bind(this), false);
    document.removeEventListener('mousemove', this.move.mouseMove.bind(this), false);
    document.removeEventListener('touchmove', this.move.touchMove.bind(this), false);
    document.removeEventListener('mouseup', this.move.mouseUp.bind(this), false);
    document.removeEventListener('touchEnd', this.move.touchEnd.bind(this), false);
    this.display = 'none';
}

它工作得很好; 但是,即使我尝试引用相同的函数,删除侦听器也不起作用。 如何删除此上下文中的侦听器?

附言我相信有一种更好的方法来注册文档事件,这也将有助于了解。

虽然一种新的重写方法可能能够使用 @HostListener Angular 方法,但这里的问题在于使用原生 JavaScript .bind() 原型方法。

bind(( 方法创建一个新函数...Function.prototype.bind((

换句话说,使用 bind 就像使用匿名函数一样,具有提供this上下文的好处,这意味着您引用的不是原始对象,而是新创建的函数。 因此,尽管我认为我显式指向同一对象以便可以删除侦听器,但在使用bind时,我必须创建对相关对象的引用并首先预绑定它,然后指向该预绑定引用:

private moveMD = this.move.mouseDown.bind(this);
private moveTS = this.move.touchStart.bind(this);
private moveMM = this.move.mouseMove.bind(this);
private moveTM = this.move.touchMove.bind(this);
private moveMU = this.move.mouseUp.bind(this);
private moveTE = this.move.touchEnd.bind(this);
@Output()
open() {
    const div = this.someDiv.nativeElement;
    div.addEventListener('mousedown', this.moveMD, false);
    div.addEventListener('touchstart', this.moveTS, false);
    document.addEventListener('mousemove', this.moveMM, false);
    document.addEventListener('touchmove', this.moveTM, false);
    document.addEventListener('mouseup', this.moveMU, false);
    document.addEventListener('touchEnd', this.moveTE, false);
    this.display = 'block';
}
@Output()
close() {
    const div = this.someDiv.nativeElement;
    div.removeEventListener('mousedown', this.moveMD, false);
    div.removeEventListener('touchstart', this.moveTS, false);
    document.removeEventListener('mousemove', this.moveMM, false);
    document.removeEventListener('touchmove', this.moveTM, false);
    document.removeEventListener('mouseup', this.moveMU, false);
    document.removeEventListener('touchEnd', this.moveTE, false);
    this.display = 'none';
}

最新更新