Mastering Custom Directives in Angular with Practical Examples and Interview Questions

Custom directives are a powerful feature in Angular that allows developers to extend HTML by creating reusable behaviors. Whether you’re styling elements dynamically or listening to DOM events, directives are essential for building scalable Angular apps.

In this blog, we’ll explore:

  • What are custom directives in Angular?
  • Types of Angular directives
  • Creating attribute directives with real examples
  • Structural vs attribute directives
  • Best practices and use cases
  • Interview questions with detailed answers

πŸ“Œ What are Directives in Angular?

In Angular, a directive is a class with a @Directive() decorator. It lets you attach behavior to DOM elements (like highlighting, showing/hiding elements, etc.) or even modify their structure.

There are three types of directives in Angular:

  1. Component directives – Have a template, essentially a directive with a view.
  2. Attribute directives – Change the appearance or behavior of an element (e.g., ngStyle, ngClass).
  3. Structural directives – Change the DOM layout (e.g., *ngIf, *ngFor, *ngSwitch).

✨ How to Create a Custom Attribute Directive

Let’s build a directive that highlights an element on mouse hover.

πŸ› οΈ Step 1: Create the Directive

ng generate directive highlight

This command generates a file highlight.directive.ts.

βœ… highlight.directive.ts

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

@Directive({
  selector: '[appHighlight]'
})
export class HighlightDirective {
  @Input() appHighlight = 'yellow';

  constructor(private el: ElementRef) {}

  @HostListener('mouseenter') onMouseEnter() {
    this.highlight(this.appHighlight);
  }

  @HostListener('mouseleave') onMouseLeave() {
    this.highlight('');
  }

  private highlight(color: string) {
    this.el.nativeElement.style.backgroundColor = color;
  }
}

πŸ§ͺ Usage in Template

<p [appHighlight]="'lightblue'">Hover me to see custom directive in action!</p>

βš’οΈ Another Practical Example: AutoFocus Directive

You might want an input field to auto-focus when the page loads.

autofocus.directive.ts

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

@Directive({
  selector: '[appAutoFocus]'
})
export class AutoFocusDirective implements AfterViewInit {
  constructor(private el: ElementRef) {}

  ngAfterViewInit() {
    this.el.nativeElement.focus();
  }
}

Usage

<input appAutoFocus type="text" placeholder="Auto focused input" />

πŸ” Structural Directive Example: Repeat N Times

Let’s create a directive that repeats an element n times.

repeat.directive.ts

import { Directive, Input, TemplateRef, ViewContainerRef } from '@angular/core';

@Directive({
  selector: '[appRepeat]'
})
export class RepeatDirective {
  @Input() set appRepeat(times: number) {
    this.vcRef.clear();
    for (let i = 0; i < times; i++) {
      this.vcRef.createEmbeddedView(this.templateRef);
    }
  }

  constructor(
    private templateRef: TemplateRef<any>,
    private vcRef: ViewContainerRef
  ) {}
}

Usage

<div *appRepeat="3">
  <p>This will appear 3 times!</p>
</div>

🎯 When Should You Use Custom Directives?

  • Apply reusable logic to DOM elements (e.g., hover, validation, auto-focus)
  • Avoid duplicating structural behavior (e.g., conditional rendering)
  • Create reusable UI behavior logic shared across components

βœ… Best Practices

  • Keep directive logic simple and reusable.
  • Prefer attribute directives for DOM behavior.
  • Avoid manipulating DOM directly unless necessary (use Renderer2 instead).
  • Always clean up subscriptions or intervals in ngOnDestroy.

πŸ€” Angular Interview Questions on Custom Directives

1. What is the difference between a component and a directive in Angular?

Answer: A component is a directive with a template. Directives (like attribute or structural) do not have a view but can modify elements or templates.


2. How do you pass parameters to a directive?

Answer: Use the @Input() decorator:

@Input() appHighlight: string;

3. What are the lifecycle hooks used in directives?

Answer: Commonly used hooks are ngOnInit, ngOnChanges, and ngOnDestroy. For structural directives, ngAfterViewInit and ngDoCheck may also be used.


4. How do structural directives differ from attribute directives?

Answer: Structural directives modify the DOM layout by adding/removing elements (*ngIf, *ngFor), while attribute directives modify element behavior/appearance (ngClass, ngStyle).


5. How can you build a reusable validation directive?

Answer: Implement Validator interface, create directive with NG_VALIDATORS provider.

@Directive({
  selector: '[appValidate]',
  providers: [{ provide: NG_VALIDATORS, useExisting: ValidateDirective, multi: true }]
})
export class ValidateDirective implements Validator {
  validate(control: AbstractControl): ValidationErrors | null {
    return control.value === 'admin' ? { forbidden: true } : null;
  }
}

Leave a Comment