This page looks best with JavaScript enabled

Custom Directives in Angular 7

 ·  ☕ 6 min read  ·  ✍️ Adesh

Getting started with Directives

There are basically three types of directives:

  • Component directive - a directive with templates.
  • Attribute directive -  a directive which manipulate DOM by changing behaviour and appearance
  • Structural directive - a directive which create and destroy DOM element

Component directive is what we are using it in our day to day programming since Angular 2. So, I am going to skip discussing about Component directive. In this post, we will briefly discuss the rest of the two directives: Attribute and Structural directives.

Structural Directives

Structural directives are used to add, remove or manipulate the elements from the DOM. It is easy to identify structural directives. Structural directives are prefixed by asterisk (*) with the directive name. Example of structural directives are : NgIf, NgSwitch & NgFor. These are inbuilt structural directives.

Attribute Directives

Attribute directives are used to change the behavior and appearance of an DOM element. As the name suggests, they are applied as an attribute on the DOM element.

1
2
<p [style.color]="'red'">attribute directive</p>
<p [hidden]="shouldHide">attribute directive</p>

Custom Directive

Let’s create our first custom directive. To generate the directive, run this command in the command terminal.

1
ng generate directive color

This command will generate a color.directive.ts file in the app folder.

color.directive.ts

1
2
3
4
5
6
7
8
import { Directive } from "@angular/core";

@Directive({
  selector: "[appColor]",
})
export class ColorDirective {
  constructor() {}
}

In the first line, Angular CLI imported Directive from @angular/core package. This will provide the @Directive decorator.

The name of our directive is appColor in the [] selector. Angular will look for this attribute on the html element, and applies the directive logic to that element. This directive has a class name ColorDirective.

This command will also add an entry in our app.module.ts file as well. See the line 7 and 13 in app.module.ts file.

app.module.ts

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
import { BrowserModule } from "@angular/platform-browser";
import { NgModule } from "@angular/core";

import { AppRoutingModule } from "./app-routing.module";
import { AppComponent } from "./app.component";
import { StructuralDirectiveComponent } from "./structural-directive/structural-directive.component";
import { ColorDirective } from "./color.directive";

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

Let’s put some code logic in our appColor directive. We are going to make the background color of an element Red. So, our directive code looks like this:

color.directive.ts

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
import { Directive, ElementRef } from "@angular/core";

@Directive({
  selector: "[appColor]",
})
export class ColorDirective {
  constructor(el: ElementRef) {
    el.nativeElement.style.backgroundColor = "red";
  }
}

If you notice in line first, we also imported ElementRef

import { Directive, ElementRef } from ‘@angular/core’;

and injected this in our directive class constructor in order to access the element, on which this directive is applied.

constructor(el: ElementRef)

After injecting ElementRef in our class constructor, we can now access the element here. So, let’s access the element and set its background color to Red.

1
2
3
constructor(el: ElementRef) {
    el.nativeElement.style.backgroundColor = 'red';
  }

This is how, we can create our basic directive. But how can we use it on any element?

To apply this directive, we have added appColor to

element.

1
<p appColor>Show me my color</p>

See the complete code of app.component.html file.

app.component.html

1
2
3
4
5
6
7
8
<!--The content below is only a placeholder and can be replaced.-->
<div style="text-align:center">
  <h1>
    Welcome to {{ title }}!
  </h1>
  <p appColor>Show me my color</p>
  <router-outlet></router-outlet>
</div>

Open the browse and see the page.

custom directive in angular 7

Here, we can see, our directive changed the red background color of the text.

So, in this way, we have modified the DOM through our custom directive. We have changed the color of p element through angular attribute directive.

Passing value to Custom Directive

In the above directive, we have hard coded the color code Red. It would be great, if we can make it dynamic, i.e, our directive can accept any color name from the element and render the background in same color. In order to make our custom directive dynamic, let’s tweak our code again.

color.directive.ts

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
import { Directive, ElementRef, Input, OnInit } from "@angular/core";

@Directive({
  selector: "[appColor]",
})
export class ColorDirective implements OnInit {
  @Input() appColor: string;

  constructor(private el: ElementRef) {}

  ngOnInit() {
    this.el.nativeElement.style.backgroundColor = this.appColor;
  }
}

In the line first, we have further imported OnInit from @angular/core.

import { Directive, ElementRef, Input, OnInit } from ‘@angular/core’;

OnInit

A lifecycle hook that is called after Angular has initialized all data-bound properties of a directive. Define an ngOnInit() method to handle any additional initialization tasks.

After importing OnInit, we implemented this directive in our class in line 6.

export class ColorDirective implements OnInit

Let’s create an input property in our directive named same as our directive name.

@Input() appColor: string;

Then implements the ngOnInit() method. In this method, we wrote the code of setting the background color of an element to the color, passed through element to our directive.

1
2
3
ngOnInit(){
    this.el.nativeElement.style.backgroundColor = this.appColor;
  }

Now, let’s see the code in our html template file, how to use this directive now.

app.component.html

1
2
3
4
5
6
7
8
9
<!--The content below is only a placeholder and can be replaced.-->
<div style="text-align:center">
  <h1>
    Welcome to {{ title }}!
  </h1>
  <p [appColor]="'green'">Show me Green Color</p>
  <p [appColor]="'red'">Show me Red Color</p>
  <router-outlet></router-outlet>
</div>

See these two lines in our template file. We have passed green & red color to

elements.

1
2
<p [appColor]="'green'">Show me Green Color</p>
<p [appColor]="'red'">Show me Red Color</p>
Note: String values must be passed with single quotes (') with double quotes (").

Now, open the browser and see the page.

custom directive in angular 7

Passing value to Custom Directive by Component Class

To make our above code more simpler, we can declare two model property in our component class app.component.ts file.

app.component.ts

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
import { Component } from "@angular/core";

@Component({
  selector: "app-root",
  templateUrl: "./app.component.html",
  styleUrls: ["./app.component.css"],
})
export class AppComponent {
  title = "zeptoapp";
  greenColor = "green";
  redColor = "red";
}

Now, you can see in line 10 & 11, we have created two model properties: greenColor & redColor. Then, we passed it to our custom directive through html template file.

app.component.html

1
2
3
4
5
6
7
8
9
<!--The content below is only a placeholder and can be replaced.-->
<div style="text-align:center">
  <h1>
    Welcome to {{ title }}!
  </h1>
  <p [appColor]="greenColor">Show me Green Color</p>
  <p [appColor]="redColor">Show me Red Color</p>
  <router-outlet></router-outlet>
</div>

In this way, we can pass custom directive values from the component class as well.

Summary

In this blog, we looked into different kinds of Angular Directives. And then we have created our custom directive. We also learned about how to pass value from html template file, and then from component class as well.

Read more:

Share on

Adesh
WRITTEN BY
Adesh
Technical Architect