directive click outside angular 6

This is a modification of @YoungHyeong Ryu answer above, but with unsubscription, so that the handler stops working when the component is unmounted.

DEMO https://stackblitz.com/edit/angular-1q4pga

import { Component, Input, OnInit, OnDestroy, ViewChild } from '@angular/core';

@Component({
  selector: 'app-click-outside',
  template: `<div #insideElement>Click outside me.</div>`
})
export class ClickOutsideComponent implements OnInit, OnDestroy  {
  @ViewChild('insideElement', { static: false }) insideElement;

  public ngOnInit() {
    this.onDocumentClick = this.onDocumentClick.bind(this);
    document.addEventListener('click', this.onDocumentClick);
  }

  public ngOnDestroy() {
    document.removeEventListener('click', this.onDocumentClick);
  }

  protected onDocumentClick(event: MouseEvent) {
    if (this.insideElement.nativeElement.contains(event.target)) {
      return;
    }
    console.log('Clicked outside!');
  }
}

Here, we remove the event listener on destroy. Also, normally a method added by addEventListener is executed in a global context (instead of this context); so we should take care of it and bind onDocumentClick method to this (we do it in ngOnInit). Now we can use this inside onDocumentClick.


You're referencing "this" in your template, which is not necessary. I made a working example of that directive:

https://stackblitz.com/edit/angular-piqewb

And theres no reason to have the directive on the div twice.

<div id="sidenav" *ngIf="opened" class="sidenav" [ngClass]="getClasses()" [ngStyle]="getStyles()" (clickOutside)="closeOutsideSidenav()">
    <header> {{ navTitle }} </header>
    <i *ngIf="showCloseButton" class="iconic iconic-x-thin close-icon" (click)="closeSidenav()"></i>
    <ng-content></ng-content>
</div>

<div *ngIf="backdrop && opened" class="sidenav-backdrop"></div>

view:

<div #insideElement></div>

component:

export class SomeClass {
  @ViewChild("insideElement") insideElement;
  @HostListener('document:click', ['$event.target'])

  public onClick(targetElement) {
    const clickedInside = this.insideElement.nativeElement.contains(targetElement);
    if (!clickedInside) {
      console.log('outside clicked');
    }
  }
}