Events of Component

https://www.notion.so/Events-of-Component-6f325676e5404b5fa600213ceef23d3e

Outside Click

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
import { Directive, Input, Output, EventEmitter, ElementRef, HostListener } from '@angular/core';

@Directive({
  selector: '[clickOutside]',
})
export class ClickOutsideDirective {

  @Output() clickOutside = new EventEmitter<void>();

  constructor(private elementRef: ElementRef) { }

  @HostListener('document:click', ['$event.target'])
  public onClick(target) {
    const clickedInside = this.elementRef.nativeElement.contains(target);
    if (!clickedInside) {
      this.clickOutside.emit();
    }
  }
}
1
<div (clickOutside)="someHandler()"></div>

Keydown of Component

1
2
3
4
5
6
7
8
  @HostListener('document: keydown', ['$event'])
  public onEnter(event: KeyboardEvent): void {
    if (this.elementRef.nativeElement.contains(event.target)) {
      if (event.code === 'Enter') {
        // TODO:
      }
    }
  }

‼️Tips

If the element contains *ngIf, this.overlay.nativeElement.contains(event.target); always return false. Because of the angular directive *ngIf

1
2
3
4
5
<div #overlay>
	<div *ngIf="show" class="item">
		Click here
  </div>
</div>
1
2
3
4
@ViewChild('overlay', { static: false }) overlay: ElementRef;

//...
this.overlay.nativeElement.contains(event.target);  // always return false

How to solve it?

You can check the event.target

1
Object.keys(event.target.classList).includes('item');

Or use [hidden] instead.

1
2
3
	<div [hidden]="!show" class="item">
		Click here
  </div>
This post is licensed under CC BY 4.0 by the author.