I have a directive that listens to some events using the host property of the @directive decorator. This works great, but I don't need all events at all times.
For example, I'm only interested in (document: mouseup) at certain times (namely after a mousedown on my element).
What is the angular way to register and unregister to events dynamically?
If you register imperatively you can unregister the same way. AFAIK for declaratively added listeners there is no way to unregister.
import {DOM} from 'angular2/platform/common_dom.dart';
DOM
.getGlobalEventTarget('window')
.addEventListener('message', function, false);
//.remove...
See also https://github.com/angular/angular/issues/6904
You could also just use
document.addEventListener
// remove ...
but direct DOM access is discouraged. But in the comments of the linked issue they seem to see the first approach as direct DOM access as well.
Not sure if you've seen the 'draggable' example that is available as part of some angular class. There is an adapted version of it in this answer. While it doesn't exactly do what you ask - ie register and de-register mousemove depending on whether we are currently dragging or not - it is one way of doing a draggable directive in angular 2.
My own slightly more general purpose version goes like this:
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));
}
}
Take that with a pinch of salt as I am currently chasing a memory leak which seems to be related to this directive. I will update if I find an issue.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With