Angular @HostBinding() and @HostListener() Example

Angular custom directives can take inputs using @HostBinding and add event listeners to elements using <strong>@HostListener</strong>. In this tutorial, we will create a custom directive example from scratch which will take user inputs from a directive element and use them in event listeners. Let’s create a new Directive in the Angular application to demonstrate an…

By.

•

min read

Angular custom directives can take inputs using @HostBinding and add event listeners to elements using <strong>@HostListener</strong>.

In this tutorial, we will create a custom directive example from scratch which will take user inputs from a directive element and use them in event listeners.

Let’s create a new Directive in the Angular application to demonstrate an element Highlighter directive which will include color input by a user and mouse events to highlight the background of a div.

Create Directive [appHighlight]

To create a new directive we will use the generate command of ng cli. Run the following command in the terminal window to creates a directive in directives folder :

$ ng generate directive directives/highlighter

Above command will create a new directive HighlighterDirective in the file src\app\directives\highlighter.directive.ts

// highlighter.directive.ts
import { Directive } from '@angular/core';

@Directive({
  selector: '[appHighlighter]'
})
export class HighlighterDirective {

  constructor() { }

}
</pre>
To use a directive we also need to import it in the <strong>app.module.ts</strong> file's <code>declaration array but NG CLI command will automatically add it as shown below:
// app.module.ts
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';

import { HighlighterDirective } from './directives/highlighter.directive';

@NgModule({
  declarations: [
    AppComponent,
    HighlighterDirective
  ],
  imports: [
    BrowserModule,
    AppRoutingModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

Add Directive Element

Now we will add a <p/> tag element with some random text in the component template HTML with two properties:

[appHighlighter] : This property will act as the Directive selector added to the element as well as take a color name or Hexacode, which will be the background color changed on the mouseenter event.
[defaultColor] : This property takes the color which will be added by default to the element.
Finally, the element with our directive will look like this:
<p 
    [appHighlighter]="'red'" 
    [defaultColor]="'yellow'"
>
  Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna
  aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
  Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint
  occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
</p>

Update Directive with @HostBinding and @HostListener

Let's add @HostBinding and @HostListener decorators and check what actually they do in a directive?

What is @HostBinding in Angular?

The host is actually the element on which we have added the directive attribute selector. By using the @HostBinding we can control the properties on the host element, on which we have applied the directive selector.

We will use this decorator to set the background color on the directive by controlling the style attribute from the directive class itself.

@HostBinding('style.backgroundColor') backgroundColor: string;</pre>
<h2>What is @HostListener in Angular?</h2>
The <code>@HostListener decorator enable event binding to the host element which we will use inside our directive class to bind mouseenter and mouseleave event listeners.
  @HostListener('mouseenter') mouseover(eventData: Event) {
    ...
  }

  @HostListener('mouseleave') mouseleave(eventData: Event) {
    ...
  }</pre>
Moving to our directive class, add <code>@input decorators to get values to form properties we bind to the <p> element. Also, add @HostBinding for getting control over style attribute to change backgroundColor.
...
export class HighlighterDirective {

  @Input() defaultColor: string = 'transparent';
  @Input('appHighlighter') highlightColor: string = 'blue';
  @HostBinding('style.backgroundColor') backgroundColor: string;
...

On class initialization, set the background color of the host, which is the <p> element here with the default color using the ngOnInit() component hook.

...
  ngOnInit() {
    this.backgroundColor = this.defaultColor;
  }
...

To control mouse behavior on the element, add event listeners as shown below:

...  
  @HostListener('mouseenter') mouseover(eventData: Event) {
    this.backgroundColor = this.highlightColor;
  }

  @HostListener('mouseleave') mouseleave(eventData: Event) {
    this.backgroundColor = this.defaultColor;
  }
...</pre>
That's it now our complete <code>HighlighterDirective class will finally have the following code!
// highlighter.directive.ts
import { Directive, Input, HostBinding, HostListener } from '@angular/core';

@Directive({
  selector: '[appHighlighter]'
})
export class HighlighterDirective {

  @Input() defaultColor: string = 'transparent';
  @Input('appHighlighter') highlightColor: string = 'blue';
  @HostBinding('style.backgroundColor') backgroundColor: string;

  constructor() { }

  ngOnInit() {
    this.backgroundColor = this.defaultColor;
  }

  @HostListener('mouseenter') mouseover(eventData: Event) {
    this.backgroundColor = this.highlightColor;
  }

  @HostListener('mouseleave') mouseleave(eventData: Event) {
    this.backgroundColor = this.defaultColor;
  }

}

Conclusion: Here we discussed how to control the element behavior by adding a custom directive using @HostBinding and @HostListener interfaces.

 

Leave a Reply

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