In Angular, directives are one of the most powerful features that allow you to extend HTML’s capabilities and create reusable components. While Angular provides many built-in directives like *ngIf
and *ngFor
, sometimes you need custom functionality tailored to your specific needs. That’s where custom directives come in.
This guide will walk you through how to implement custom directives in Angular in a clear, easy-to-follow way. Whether you’re a beginner or brushing up your skills, by the end you’ll know how to create attribute and structural directives that make your Angular apps more dynamic and maintainable.
What Are Custom Directives in Angular?
Directives in Angular are classes that add additional behavior to elements in your Angular templates. Custom directives let you encapsulate reusable behavior, manipulate the DOM, or respond to user events, helping keep your code clean and modular.
There are three types of directives in Angular:
- Component Directives: These are the components themselves with templates.
- Attribute Directives: Change the appearance or behavior of an element, component, or another directive.
- Structural Directives: Change the DOM layout by adding or removing elements dynamically.
This guide focuses on implementing custom attribute and structural directives.
Step 1: Setting Up Your Angular Project
If you haven’t created an Angular project yet, start by running:
bash
ng new custom-directive-demo
cd custom-directive-demo
ng serve
Once your project is up and running, you can start adding your custom directives.
Step 2: Creating a Custom Attribute Directive
Let’s create a simple directive that changes the background color of an element when you hover over it.
- Generate a directive using Angular CLI:
bash
ng generate directive hoverHighlight
This command creates two files:
hover-highlight.directive.ts
hover-highlight.directive.spec.ts
(for testing)
- Open
hover-highlight.directive.ts
and modify the code as follows:
typescript
import { Directive, ElementRef, HostListener, Input } from ‘@angular/core’;
@Directive({
selector: ‘[appHoverHighlight]’
})
export class HoverHighlightDirective {
@Input() highlightColor: string = ‘yellow’;
constructor(private el: ElementRef) { }
@HostListener(‘mouseenter’) onMouseEnter() {
this.highlight(this.highlightColor);
}
@HostListener(‘mouseleave’) onMouseLeave() {
this.highlight(”);
}
private highlight(color: string) {
this.el.nativeElement.style.backgroundColor = color;
}
}
Explanation:
@Input()
decorates a property so the directive user can specify the color.@HostListener
listens to DOM events in the host element (e.g., mouseenter and mouseleave).ElementRef
gives direct access to the DOM element.
- Use the directive in your component’s HTML:
Hover over me to see the highlight effect!
Try hovering, and you’ll see the background color changing dynamically!
Step 3: Creating a Custom Structural Directive
Structural directives change the DOM by adding or removing elements. Let’s build a simple directive that shows elements only if a condition is met, similar to *ngIf
.
- Generate the directive:
bash
ng generate directive unless
- Modify
unless.directive.ts
:
typescript
import { Directive, Input, TemplateRef, ViewContainerRef } from ‘@angular/core’;
@Directive({
selector: ‘[appUnless]’
})
export class UnlessDirective {
private hasView = false;
constructor(
private templateRef: TemplateRef
private viewContainer: ViewContainerRef
) { }
@Input() set appUnless(condition: boolean) {
if (!condition && !this.hasView) {
this.viewContainer.createEmbeddedView(this.templateRef);
this.hasView = true;
} else if (condition && this.hasView) {
this.viewContainer.clear();
this.hasView = false;
}
}
}
How It Works:
TemplateRef
stores the template where the directive is applied.ViewContainerRef
is the container that holds one or more views.- The directive adds the template to the DOM only when the
condition
isfalse
.
- Use it in your component template:
<div *appUnless=”isLoggedIn”>
Please log in to access this content.