1

I'm trying to check which event listener to set by checking 'ontouchstart' in window ? 'touchend' : 'click', and then I want to add this inside a @HostListener but I'm unable to do this because this is not available in the document:click section.

Can you achieve this somehow?

constructor(private _globals: GlobalVariablesService, private _elementRef: ElementRef) {
  this.ns = _globals.ns;
  this.deviceListener = ('ontouchstart' in window ? 'touchend' : 'click');
}

// How can I add the this.deviceListener instead of click?
@HostListener('document:click', ['$event'])
onOutsideClick(e) {
  const nativeElement = this._elementRef.nativeElement;

  // If the clicked element is not the component element or any of its children, close the dropdown
  if (nativeElement !== e.target && !nativeElement .contains(e.target)) {
    this.close();
  }
}
Johan Aspeling
  • 765
  • 1
  • 13
  • 38
Chrillewoodz
  • 27,055
  • 21
  • 92
  • 175
  • See if this helps: http://stackoverflow.com/questions/35080387/dynamically-add-event-listener-in-angular-2. Basically, add it imperatively inside your constructor. – Mark Rajcok May 24 '16 at 18:52
  • @MarkRajcok After an answer to a question I posted yesterday I was under the impression that you shouldn't add event listeners like that. – Chrillewoodz May 24 '16 at 18:58
  • What class variable do you try to access? What's the problem with accessing `deviceListener`? `this.deviceListener` should just work in `onOutsideClick() { ... }` – Günter Zöchbauer May 24 '16 at 18:58
  • @GünterZöchbauer I can access the variable inside onOutsideClick without a problem, but that's not where I tell angular which events to listen for. That's done in the `@HostListener('document:click', ['$event'])` part, and instead of writing `document:click` I would like to write `this.deviceListener`. Does that make it more clear? – Chrillewoodz May 24 '16 at 19:01
  • I think I got it now. I guess this doesn't work with `@HostListener()` Use `Renderer` like in the answer linked above by @MarkRajcok instead if you need this. – Günter Zöchbauer May 24 '16 at 19:02
  • @GünterZöchbauer, I think he wants to write this, but can't: `@HostListener('document:' + this.deviceListener, ...)`. However, this seems to work okay: `@HostListener('document:' + ('ontouchstart' in window ? 'touchend' : 'click'), ...)` – Mark Rajcok May 24 '16 at 19:06
  • Chrillewoodz, regarding the [question](http://stackoverflow.com/questions/37376442/where-does-dom-manipulation-belong-in-angular-2) you posted yesterday... shouldn't add event listeners using `window.addEventListener()`. Using Renderer is fine. – Mark Rajcok May 24 '16 at 19:20

1 Answers1

3

Use

@HostListener('document:' + ('ontouchstart' in window ? 'touchend' : 'click'), ...)

or add it imperatively inside your constructor, as shown in this question: Dynamically add event listener in Angular 2:

constructor(elementRef: ElementRef, renderer: Renderer) {
   if('ontouchstart' in window) {
       this.listenFn = renderer.listenGlobal('document', 'ontouchstart', (event) => {
           // do something with 'event'
       });
   } else {
       this.listenFn = renderer.listenGlobal('document', 'click', (event) => {
           // do something with 'event'
       });
   }
}
ngOnDestroy() {
    this.listenFn();  // removes the listener
}

If you add it imperatively, be sure to remove it imperatively.

Community
  • 1
  • 1
Mark Rajcok
  • 362,217
  • 114
  • 495
  • 492