使用Angular 2以编程方式(un)注册事件

时间:2016-02-10 11:40:31

标签: javascript angular

我有一个使用host装饰器的@directive属性侦听某些事件的指令。这很好用,但我不是一直都需要所有活动。

例如,我在某些时候(即在我的元素上被诅咒之后)只对(document: mouseup)感兴趣。

动态注册和取消注册事件的角度方式是什么?

2 个答案:

答案 0 :(得分:3)

如果您必须注册,则可以以相同的方式取消注册。 AFAIK用于声明性添加的侦听器,无法取消注册。

import {DOM} from 'angular2/platform/common_dom.dart';

DOM
    .getGlobalEventTarget('window')
    .addEventListener('message', function, false);
    //.remove...

另见https://github.com/angular/angular/issues/6904

您也可以使用

document.addEventListener
        // remove ...

但不鼓励直接访问DOM。但是在链接问题的评论中,他们似乎也将第一种方法视为直接DOM访问。

答案 1 :(得分:1)

不确定您是否已经看过“可拖动的”'作为某个角度类的一部分可用的示例。在this answer中有一个改编的版本。虽然它并没有完全符合你的要求 - 即根据我们当前是否正在拖动来注册和取消注册mousemove - 这是在角度2中执行可拖动指令的一种方式。

我自己稍微更通用的版本是这样的:

import {Directive, EventEmitter, HostListener, Output} from 'angular2/core';
import {Observable} from 'rxjs/Observable';

@Directive({
  selector: '[draggable]'
})
export class DraggableDirective {

  @Output() mousedrag: Observable<{x: number, y: number}>;
  @Output() dragend = new EventEmitter<void>();
  mousedown = new EventEmitter<MouseEvent>();
  mousemove = new EventEmitter<MouseEvent>();
  dragActive = false;

  @HostListener('document:mouseup', ['$event'])
  onMouseup(event) {
    if(this.dragActive) {
      this.dragend.emit(null);
      this.dragActive = false;
    }
  }

  @HostListener('mousedown', ['$event'])
  onMousedown(event: MouseEvent) {
    this.mousedown.emit(event);
  }

  @HostListener('document:mousemove', ['$event'])
  onMousemove(event: MouseEvent) {
    if(this.dragActive) {
      this.mousemove.emit(event);
      return false;
    }
  }

  constructor() {
    this.mousedrag = this.mousedown.map((event) => {
      this.dragActive = true;
      return { x: event.clientX, y: event.clientY };
    }).flatMap(mouseDownPos => this.mousemove.map(pos => {
      return { x: pos.clientX - mouseDownPos.x, y: pos.clientY - mouseDownPos.y };
    }).takeUntil(this.dragend));
  }
}

因为我正在追逐一个似乎与此指令相关的内存泄漏,所以需要一点点盐。如果我发现问题,我会更新。