Notice: This page requires JavaScript to function properly.
Please enable JavaScript in your browser settings or update your browser.
Learn Creating Custom Directives in Angular | Mastering Angular Directives and Pipes
Introduction to Angular
course content

Course Content

Introduction to Angular

Introduction to Angular

1. Angular Fundamentals
2. Components and Templates
3. Mastering Angular Directives and Pipes
4. Services and Dependency Injection in Angular
5. Standalone Components & Modules
6. Routing and Navigation in Angular

book
Creating Custom Directives in Angular

Angular comes with a set of built-in directives like ngIf, ngFor, and ngClass. But you can also create your own custom directive to handle specific tasks in your application. Let's walk through how to build one with a practical example.

Generate the Custom Directive

First, it's a good practice to organize your code by creating a dedicated folder for your directives. Let's call it directives.

This command creates a new folder named directives inside the app directory and adds the new directive file inside it:

  • highlight-on-complete.directive.ts – contains the directive's logic;

  • highlight-on-complete.directive.spec.ts – unit test file (you can delete it if not needed).

Here's what the basic structure of the directive looks like:

ts

highlight-on-complete

copy
12345678
import { Directive } from '@angular/core'; @Directive({ selector: '[appHighlightOnComplete]' }) export class HighlightOnCompleteDirective { constructor() {} }

Define What the Directive Should Do

This directive will highlight a task element in green if it's marked as completed. Otherwise, it will clear the styles.

To tell Angular that this class is a directive, we decorate it with @Directive:

ts

The selector [appHighlightOnComplete] means the directive will be used as an attribute, not as a tag or structural directive.

In your HTML, you'll apply it like this:

ts

Make the Directive React to Changes

To detect changes to the completed input, we implement the OnChanges interface:

ts

highlight-on-complete

copy
1
export class HighlightOnCompleteDirective implements OnChanges {}

We also define an input property to receive the value from the component:

ts

highlight-on-complete

copy
123
export class HighlightOnCompleteDirective implements OnChanges { @Input('appHighlightOnComplete') completed: boolean = true; }

What this does:

  • Informs Angular that the value will be provided from the template (earlier, we passed task.complete from the template);

  • Binds the directive's internal completed property to the value passed in from the template;

  • Sets a default value of true (which will be overridden once actual data is received).

Access the DOM Safely

Angular uses dependency injection to provide access to the DOM and rendering tools.

In the constructor, we inject:

ts

highlight-on-complete

copy
123456
export class HighlightOnCompleteDirective implements OnChanges { @Input('appHighlightOnComplete') completed: boolean = true; constructor(private el: ElementRef, private renderer: Renderer2) {} }

ElementRef gives us a reference to the host DOM element. Renderer2 allows us to safely modify styles and attributes without directly manipulating the DOM.

React to Changes with ngOnChanges

Now let's implement the main logic in ngOnChanges, which runs whenever the input value changes.

Full implementation:

ts

highlight-on-complete

copy
12345678910111213141516171819
@Directive({ selector: '[appHighlightOnComplete]' }) export class HighlightOnCompleteDirective implements OnChanges { @Input('appHighlightOnComplete') completed: boolean = true; constructor(private el: ElementRef, private renderer: Renderer2) {} ngOnChanges(changes: SimpleChanges): void { if (this.completed) { this.renderer.setStyle(this.el.nativeElement, 'border', '2px solid green'); this.renderer.setStyle(this.el.nativeElement, 'backgroundColor', '#e6ffe6'); } else { this.renderer.removeStyle(this.el.nativeElement, 'border'); this.renderer.removeStyle(this.el.nativeElement, 'backgroundColor'); } } }

The ngOnChanges method is triggered whenever Angular detects changes to the directive's input properties.

In this case, it responds to updates to the completed value passed from the template. If completed is true, the directive adds a green border and a light green background to the element. If it's false, those styles are removed, returning the element to its original appearance. This provides a visual indication of completed tasks.

This custom directive lets you encapsulate style behavior in a reusable, clean way. You can now apply it to any element in your app, without duplicating logic across components. It's a great example of how Angular's directive system can help you write more modular and maintainable code.

Everything was clear?

How can we improve it?

Thanks for your feedback!

SectionΒ 3. ChapterΒ 4

Ask AI

expand
ChatGPT

Ask anything or try one of the suggested questions to begin our chat

course content

Course Content

Introduction to Angular

Introduction to Angular

1. Angular Fundamentals
2. Components and Templates
3. Mastering Angular Directives and Pipes
4. Services and Dependency Injection in Angular
5. Standalone Components & Modules
6. Routing and Navigation in Angular

book
Creating Custom Directives in Angular

Angular comes with a set of built-in directives like ngIf, ngFor, and ngClass. But you can also create your own custom directive to handle specific tasks in your application. Let's walk through how to build one with a practical example.

Generate the Custom Directive

First, it's a good practice to organize your code by creating a dedicated folder for your directives. Let's call it directives.

This command creates a new folder named directives inside the app directory and adds the new directive file inside it:

  • highlight-on-complete.directive.ts – contains the directive's logic;

  • highlight-on-complete.directive.spec.ts – unit test file (you can delete it if not needed).

Here's what the basic structure of the directive looks like:

ts

highlight-on-complete

copy
12345678
import { Directive } from '@angular/core'; @Directive({ selector: '[appHighlightOnComplete]' }) export class HighlightOnCompleteDirective { constructor() {} }

Define What the Directive Should Do

This directive will highlight a task element in green if it's marked as completed. Otherwise, it will clear the styles.

To tell Angular that this class is a directive, we decorate it with @Directive:

ts

The selector [appHighlightOnComplete] means the directive will be used as an attribute, not as a tag or structural directive.

In your HTML, you'll apply it like this:

ts

Make the Directive React to Changes

To detect changes to the completed input, we implement the OnChanges interface:

ts

highlight-on-complete

copy
1
export class HighlightOnCompleteDirective implements OnChanges {}

We also define an input property to receive the value from the component:

ts

highlight-on-complete

copy
123
export class HighlightOnCompleteDirective implements OnChanges { @Input('appHighlightOnComplete') completed: boolean = true; }

What this does:

  • Informs Angular that the value will be provided from the template (earlier, we passed task.complete from the template);

  • Binds the directive's internal completed property to the value passed in from the template;

  • Sets a default value of true (which will be overridden once actual data is received).

Access the DOM Safely

Angular uses dependency injection to provide access to the DOM and rendering tools.

In the constructor, we inject:

ts

highlight-on-complete

copy
123456
export class HighlightOnCompleteDirective implements OnChanges { @Input('appHighlightOnComplete') completed: boolean = true; constructor(private el: ElementRef, private renderer: Renderer2) {} }

ElementRef gives us a reference to the host DOM element. Renderer2 allows us to safely modify styles and attributes without directly manipulating the DOM.

React to Changes with ngOnChanges

Now let's implement the main logic in ngOnChanges, which runs whenever the input value changes.

Full implementation:

ts

highlight-on-complete

copy
12345678910111213141516171819
@Directive({ selector: '[appHighlightOnComplete]' }) export class HighlightOnCompleteDirective implements OnChanges { @Input('appHighlightOnComplete') completed: boolean = true; constructor(private el: ElementRef, private renderer: Renderer2) {} ngOnChanges(changes: SimpleChanges): void { if (this.completed) { this.renderer.setStyle(this.el.nativeElement, 'border', '2px solid green'); this.renderer.setStyle(this.el.nativeElement, 'backgroundColor', '#e6ffe6'); } else { this.renderer.removeStyle(this.el.nativeElement, 'border'); this.renderer.removeStyle(this.el.nativeElement, 'backgroundColor'); } } }

The ngOnChanges method is triggered whenever Angular detects changes to the directive's input properties.

In this case, it responds to updates to the completed value passed from the template. If completed is true, the directive adds a green border and a light green background to the element. If it's false, those styles are removed, returning the element to its original appearance. This provides a visual indication of completed tasks.

This custom directive lets you encapsulate style behavior in a reusable, clean way. You can now apply it to any element in your app, without duplicating logic across components. It's a great example of how Angular's directive system can help you write more modular and maintainable code.

Everything was clear?

How can we improve it?

Thanks for your feedback!

SectionΒ 3. ChapterΒ 4
We're sorry to hear that something went wrong. What happened?
some-alt