Custom Directives

Overview

With custom directives, we can extend the framework's functionality by creating our own reusable directives. In this article, we will delve into the process of creating custom directives in Angular, explaining each step in detail.

Understanding Custom Directives

In Angular, a directives is a class that you can attach to an HTML element to provide additional behavior or functionality. There are two main types of directives: structural and attribute directives. Structural directives, such as *ngIf and *ngFor, modify the structure of the DOM. Attributes directives, like ngStyle and ngClass , manipulate the appearance or behavior of elements.

Creating custom directives in Angular empowers you to encapsulate specific behavior or functionality and reuse it across your application. Whether you want to add custom validation, create custom tooltips, or manipulate the DOM in a unique way, custom directives can help you achieve your goals efficiently.

Creating a Custom Directive

Let's walk through the process of creating a simple custom directive step by step:

Step 1: Generate a New Directive

To create a custom directive, you can use Angular CLI's ng generate directive command. Open your terminal and run:

ng generate directive my-custom-directive

This command will generate the necessary files for your custom directive, including a TypeScript file, a test file, and an HTML file.

Step 2: Define the Directive

Open the generated TypeScript file (my-custom-directive.directive.ts) and define your custom directive class. You will need to import the necessary dependencies from Angular's core library.

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

@Directive({
  selector: '[appMyCustomDirective]'
})
export class MyCustomDirectiveDirective {
  constructor(private el: ElementRef) { }

  // Define your custom directive logic here
}

In this example, we have created a directive named appMyCustomDirective that can be applied to any element using the attribute [appMyCustomDirective].

Step 3: Implement the Directive Logic

Inside the MyCustomDirectiveDirective class, you can implement the logic for your custom directive. For instance, let's create a directive that changes the background color of an element when it's clicked.

@Directive({
  selector: '[appMyCustomDirective]'
})
export class MyCustomDirectiveDirective {
  constructor(private el: ElementRef) { }

  @HostListener('click') onClick() {
    this.el.nativeElement.style.backgroundColor = 'lightblue';
  }
}

In this code, we use the @HostListener decorator to listen for the click event on the host element (the element with the [appMyCustomDirective] attribute). When the element is clicked, we change its background color to lightblue.

Step 4: Use the Custom Directive

Now that you have created your custom directive, you can use it in your HTML templates just like any other Angular directive. For example:

<button appMyCustomDirective>Click me!</button>

When you click the button, the custom directive will be activated, and the background color of the button will change to lightblue.

Let's Modify Our ‘my-angular-project’

Now its time to modify the angular project which we built while setting up the development environment. We will add a custom directive named as bluebackground , this will just turn the element background to blue on whoever element we applied it on.

Step 1: Create directive

For creating custom directive we executed the below command:

ng generate directive bluebackground

It create the two files named as bluebackground.directive.spec.ts (a test file) and bluebackground.directive.ts both of these files is created in src/app directory.

This command also added reference for the custom directive in app.module.ts.

image-7.png

Step 2: Modify the bluebackground.directive.ts file

Open the bludebackground.directive.ts file and add the logic to apply background color to blue to bind element.

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

@Directive({
  selector: '[appBluebackground]'
})
export class BluebackgroundDirective {

  constructor(private el: ElementRef, private renderer: Renderer2) {
    this.renderer.setStyle(this.el.nativeElement, 'background-color', 'blue');
   }

}

Import Statements:

import { Directive, ElementRef, Renderer2 } from '@angular/core';
  • The Directive import is used to define the custom directive.
  • ElementRef allows access to the host element, the element to which the directive is applied.
  • Renderer2 is used for rendering-related operations in a platform-agnositc way,

Directive Definition:

@Directive({
  selector: '[appBluebackground]'
})
  • The @Directive decorator is used to define a custom directive.
  • The selector property specifies the attribute selector that activates the directive. In this case, [appBluebackground] means the directive to be applied to any HTML element with the attribute appBluebackground.

Constructor:

constructor(private el: ElementRef, private renderer: Renderer2) {
  this.renderer.setStyle(this.el.nativeElement, 'background-color', 'blue');
}
  • The Constructor of the BluebackgroundDirective class is where the directive's logic is implemented.
  • el is an instance of ElementRef, which provides access to the host element (the element to which the directive is applied).
  • renderer is an instance of Renderer2 , which allows you to manipulate the DOM in a platform-independent way.

Directive Logic:

this.renderer.setStyle(this.el.nativeElement, 'background-color', 'blue');
  • Inside the constructor, the setStyle method of Renderer2 is used to set the background color of the host element (el.nativeElement) to blue. This effectively changes the background color of the element to blue.

Step 3: Apply directive to the element

For our case we would be applying our custom directive to the buttons.

Before applying directive

After applying directive

We have applied the custom directive to the five buttons in our sample angular project and as you can see in the screenshot above, all of them turned blue in background color.

Below is the snippet code on how I applied the custom directive to a single element.

<a appBluebackground target="_blank" rel="noopener" href="https://angular.io/tutorial">
   <svg xmlns="http://www.w3.org/2000/svg" width=24 height=24 viewBox="0 0 24 24"><path d="M5 13.18v4L12 21l7-3.82v-4L12 17l-7-3.82zM12 3L1 9l11 6 9-4.91V17h2V9L12 3z"/></svg>
   <span>Learn Angular</span>
   <svg xmlns="http://www.w3.org/2000/svg" width=24 height=24 viewBox="0 0 24 24"><path d="M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z"/></svg>  </a>

You can see that we have used appBluebackground as selector for our custom directive.