What are angular hostbinding and angular hostlistener ?

An angular directive is instructions or guidelines for rendering a template. The directive allows us to change the appearance or behavior of a DOM element. An Angular offers lots of built-in directives, which we had learned in the previous article. We can create our own custom directive to have a feature that is specific to our application needs which is not supported by the built-in directive.

In this article, we will learn why we need to use angular @hostBinding and @hostListener decorator and demonstrate an example of each to manipulate DOM element using angular custom directive.

Why we need angular hostbinding and angular hostlistener ?

We have already learned that the Angular directive allows us to manipulate or change the appearance of the DOM element. That means we need a way to access the DOM element that the directive is being applied to, as well as ways to modify the DOM element. Angular provides a different way to access the DOM element as follows.

  1. Angular ElementRef class to direct access DOM element for manipulation.
  2. Angular renderer2 class allows manipulation of DOM elements without touching DOM directly.
  3. Use of Angular hostbinding and Angular hostlistener decorator without injecting in our custom directive.

By using ElementRef to manipulate DOM element involved risk of XSS attack. The first reason for using both angular hostbinding and host listener decorator allows us to access and manipulate the DOM element. If angular custom directive relies heavily on browser DOM API for DOM element manipulation then it works perfectly in the browser but angular can run on different environments, as result it may have issues with the non-browser environment. Angular provides us angular hostbinding and angular hostlistener decorator to solve the above issue.

What is the use of @HostBinding and @HostListener in angular. ?

We can use @HostBinding, @HostListerner decorator, renderer2, and ElementRef to communicate and manipulate the appearance or behavior of the host element by the angular custom directive. It is not recommended to manipulate the DOM directly with ElementRef class, because of security reasons. We can also use the @HostBinding directive to bind a DOM property of the element to an instance variable in your Angular directive. Then we can update the value of the variable, and the DOM property will automatically be updated to match.

The @HostBinding and @HostListener are two decorators in Angular that can be really useful in custom directives. These two decorators are used to access the properties and events of host elements in the directive. Bindings on the host element are defined using two decorators, @HostBinding and @HostListener, both of which are defined in the @angular/core module.

Angular @HostBinding:  allows directives to communicate with their host element by setting the properties of the host element. The @HostBinding decorator to bind a DOM property of the element to an instance variable in our custom Angular directive. When we update the value of the variable, and the DOM property will automatically be updated to match. Let’s say you want to change the style properties like the background color of the host element.

Angular @HostListener: allows interaction with the events on the host element. The @HostListener decorator allows a directive to listen to events on its host element. We can do this by decorating a function on the component with the @HostListener() decoration. The directive can listen to events with the help of the HostListener decorator. Officially an Angular definition of @HostListner “Decorator that declares a DOM event to listen for, and provides a handler method to run when that event occurs”

Example of Angular hostbinding and angular hostlistener decorator.

Here, we are using the Angular @HostBinding() decorator to access the property on the host element to set/remove its background color by listening to mouseover and mouseout event on the host by @HostListener.
Let first create an Angular project and create a custom directive hover to manipulate the DOM element appearance.

ng new custDirectiveApp
ng generate directive hoverer

The above command will create an angular project and generate a custom directive called hoverer.directive.ts file. We need to declare our custom directive in the module where we want to use it. Angular CLI will automatically add and declare hoverer directive class name in app.module.ts when we generate a custom directive. Here is a screenshot of our example.

Angular hostlistener and angular hostbinding
import { Directive, Input, HostBinding, HostListener } from '@angular/core';

@Directive({
    selector: '[hoverer]',
})
export class HovererDirective {
    @HostBinding('style.background') backgroundColor: string;


    @HostListener('mouseover') onMouseOver() {
        this.backgroundColor = 'red';
    }

    @HostListener('mouseout') onMouseOut() {
        this.backgroundColor = 'none';
    }
}

In our custom directive, we have two listener methods on the host element.
1. mouseover: event method is called when the mouse hovers on our H1 element. Based on hover we change the background color to red and you can change any style based on your requirement.
2. mouseout: event method is called when the mouse moves away from our h1 element and based on the event we remove background color.

Edit app.component.html to add our custom hoverer directive as

<div class="container">
  <h1 hoverer>Hover over me</h1>
</div>

Following are some of the example where we use HostBinding to set property like

@HostBinding(‘style.height’) height:string;
@HostBinding(‘style.color’) color: string;
@HostBinding(‘style.border-color’) borderColor: string;
@HostBinding(‘attr.role’) role = ‘button’;
@HostBinding(‘class.pressed’) isPressed: boolean;

Angular hostlistener to dynamic add and remove class

We have another example on angular hostlistener to dynamic add or remove CSS class on DOM element. We have @HostListener decorator will listen to the click event on the host element, in our case, it is a button. When a user clicks on the button we will use renderer2 to retrieve the next sibling element. We will use renderer2 to add/remove show class on a sibling element to control hide/show sibling element. Check complete example on our article on angular hostlistener to add or remove CSS class.

Example of Angular hostlistener on Input text element

Now let’s apply the angular hostlistener decorator to a text input element. When a user enters a decimal number with more than two fraction numbers we are round up and the user can’t enter more than two fraction numbers. Here is a screenshot of hostlistener on text input.

Angular hostlistener input

Let generate our custom decorator called maxTwoDecimal using angular cli.

ng g directive maxTwoDecimal

Let’s edit our custom directive of input hostlistener file called max-two-decimal.directive.ts

import { Directive, ElementRef, HostListener, Input } from '@angular/core';

@Directive({
  selector: '[appMaxTwoDecimal]'
})
export class MaxTwoDecimalDirective {

  @Input() appMaxTwoDecimal: number;

  constructor(private elRef: ElementRef) { }

  @HostListener('input') onInput(event) {
    const num = this.elRef.nativeElement.value;
    if (num && (num - Math.floor(num) !== 0)) {
      this.elRef.nativeElement.value = parseFloat(num).toFixed(2)
    }
  }

}

Here we have hostlistener input event, where we are checking if number have fraction, if so then we return only two fraction number even user enter more than two.

Now let applied our custom directive input angular hostlistener on component template, here we are applying in app.component template and let edit it.

<h2>Enter a number with decimal</h2>
<input type="number" [appMaxTwoDecimal]="3">

<router-outlet></router-outlet>

Applying angular hostlistener on document element

In our previous example, we have applied angular hostlistener input on text input and we can applied hostListener to any element. In this example we applied angular hostlister keyboard down event on document element. When user press keyboard character g then we are setting document color to green, if charact b is press then set background to blue other wise to yellow. Here is screenshot of our example.

Angular hostlistener keydown event

Let edit our app.component.ts file to add our logic for angular listener keydown event on document to change background color.

import { Component, ElementRef, HostListener, Renderer2 } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent {

  constructor(
    private elRef: ElementRef,
    private renderer: Renderer2) { }

  @HostListener('document:keydown', ['$event'])
  handleKeyboardEvent(event: KeyboardEvent) {
    if (event.key == 'g') {
      this.renderer.setStyle(this.elRef.nativeElement.ownerDocument.body,'backgroundColor', 'green');
    } else if (event.key == 'b') {
      this.renderer.setStyle(this.elRef.nativeElement.ownerDocument.body,'backgroundColor', 'blue');
    } else {
      this.renderer.setStyle(this.elRef.nativeElement.ownerDocument.body,'backgroundColor', 'yellow');
    }
  }
}

We have to inject angular elementRef and renderer2 in our component constructor. When user press key character g we are setting document background color green, if b then to blue background and otherwise to yellow background color to document.

Conclusion
In this article, we have explored details on Angular hostbinding and angular hostlistener. We have learned why we need this two decorators to manipulate the DOM element. We had demonstrated an example of both decorators. I hope that this article was able to get you up and running with angular hostbinding and angular hostlistener.

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top