@HostListener in Angular

By Arvind Rai, April 01, 2024
On this page, we will learn to use @HostListener decorator in our Angular application. We need to create a handler method decorated with @HostListener and configure event to listen. This handler method can be created in a Directive or Component. @HostListener can also pass arguments to handler method.
Now let us deep dive on using @HostListener with examples.

@HostListener

@HostListener decorator listens the specified DOM event. It is decorated at a handler method that executes when the host element emits specified event.
@HostListener has following arguments.
eventName : Event name to listen.
args : A set of arguments to pass to handler method. It is optional.
Find the code snippet.
1. With event name.
@HostListener('mouseover') 
handleMouseOver() {
   ------
} 
Here @HostListener listens the mouseover event and executes handleMouseOver() method when the host element emits mouseover event.
@HostListener is used to update host element on an event. Host element can change its style or value for an event.
2. With event name and arguments.
@HostListener('click', ['$event.target'])
handleClick(el) {
   ------
} 
The handleClick() will execute when host element emits click event and $event.target is passed as an argument.

@HostListener with 'keydown' and 'keyup' Events:

@HostListener can be used with keydown and keyup events for global window as below.
1. For Enter key.
@HostListener('window:keydown.enter')
@HostListener('window:keyup.enter') 
2. Enter key with shift.
@HostListener('window:keydown.shift.enter')
@HostListener('window:keyup.shift.enter') 
3. Any character such as 'z'
@HostListener('window:keydown.z')
@HostListener('window:keydown.shift.z') 
4. For tab.
@HostListener('window:keydown.tab') 
For any key down event.
@HostListener('window:keydown') 

Example-1: Listen 'click' Event

Here I am creating a directive to listen click event using @HostListener. The code will listen the number of clicks on button.
Find the code.
click-count.directive.ts
import { Directive, HostListener } from "@angular/core";

@Directive({
  selector: '[clickCount]',
  standalone: true
})
export class ClickCountDirective {
  count = 0;

  @HostListener('click', ['$event'])
  handleClick(ev: Event) {
    console.log('Click count for ', ev.target, ' : ', this.count++);
  }
} 
handleClick() method is decorated with @HostListener to listen 'click' event and pass Event object as an argument. handleClick() will execute when click event is emitted by host element and receives Event object as an argument. Inside method, I am just counting the clicks.
Find the component to use this directive.
app.component.ts
import { Component } from '@angular/core';
import { ClickCountDirective } from './click-count.directive';

@Component({
  selector: 'app-root',
  standalone: true,
  imports: [ClickCountDirective],
  template: `
         <button clickCount>Click</button>
  `
})
export class AppComponent {
} 
When button is clicked, we get the click count in console.

We can use @HostListener in component, too. Find the component.
app.component.ts
import { Component, HostListener } from '@angular/core';
import { ClickCountDirective } from './click-count.directive';

@Component({
  selector: 'app-root',
  standalone: true,
  imports: [ClickCountDirective],
  template: `
         <button>Button1</button>
         <button>Button2</button>
         <div>DIV</div>
  `
})
export class AppComponent {
  count = 0;

  @HostListener('click', ['$event'])
  handleClick(ev: Event) {
    console.log('Click count for ', ev.target, ' : ', this.count++);
  }
} 
In above component, we will observe that for clicks on any element of HTML, will execute handleClick() method.

Example-2 : Listen 'mouseover' and 'mouseleave' Events

In this example, I am listening 'mouseover' and 'mouseleave' events using @HostListener decorator.
mouse.directive.ts
import { Directive, ElementRef, HostListener, Renderer2 } from '@angular/core';

@Directive({
  selector: '[toggleColor]',
  standalone: true
})
export class MouseDirective {
  constructor(private elRef: ElementRef) { }
  @HostListener('mouseover')
  handleMouseOver() {
    this.elRef.nativeElement.style.color = 'green';
  }
  @HostListener('mouseleave') handleMouseLeave() {
    this.elRef.nativeElement.style.color = 'red';
  }
} 
Use directive as below.
<h3 toggleColor>Hello World!</h3> 
handleMouseOver() is decorated with @HostListener decorator.
On mouse over, the color will be green and on mouse leave, color will be red.

Example-3 : Listen 'focusin' and 'focusout' Events

In this example, I am listening 'focusin' and 'focusout' events using @HostListener decorator.
focus.directive.ts
import { Directive, ElementRef, HostListener, Input } from '@angular/core';

@Directive({
  selector: '[bgColor]',
  standalone: true
})
export class FocusDirective {
  @Input() bgColor!: string;
  @Input() defaultColor!: string;
  constructor(private elRef: ElementRef) { }

  @HostListener('focusin')
  handleMouseOver() {
    console.log("focusin");
    this.elRef.nativeElement.style.backgroundColor = this.bgColor;
  }
  @HostListener('focusout') handleMouseLeave() {
    console.log("focusout");
    this.elRef.nativeElement.style.backgroundColor = this.defaultColor;
  }
} 
Find the HTML code to use directive.
<input [bgColor]="color" defaultColor="white"> 
To use our custom directive in standalone application, we need to import them in the component.
app.component.ts
import { Component, HostListener } from '@angular/core';
import { ClickCountDirective } from './click-count.directive';
import { FocusDirective } from './focus.directive';
import { MouseDirective } from './mouse.directive';

@Component({
  selector: 'app-root',
  standalone: true,
  imports: [ClickCountDirective, MouseDirective, FocusDirective],
  template: `
     <button clickCount>Click</button>
     <h3 toggleColor>Hello World!</h3>
     <input [bgColor]="color" defaultColor="white">
  `
})
export class AppComponent {
  color = "cyan";
} 
Find the print-screen of the output.
@HostListener in Angular

Reference

POSTED BY
ARVIND RAI
ARVIND RAI
LEARN MORE












©2024 concretepage.com | Privacy Policy | Contact Us