Exploring Angular Directives: A Comprehensive Guide
Tags: webdev, javascript, beginners, angular
Published: 2024-06-08 06:15:00

Angular directives are one of the core building blocks of the Angular framework. They allow developers to extend HTML's capabilities by creating new HTML elements, attributes, classes, and comments. Directives can be used to manipulate the DOM, apply styles, manage forms, and more.

In this blog, we'll dive deep into Angular directives, exploring their types, usage, and how to create custom directives with practical code examples.

### Table of Contents
1. What are Angular Directives?
2. Types of Directives
   - Attribute Directives
   - Structural Directives
   - Component Directives
3. Creating Custom Directives
   - Custom Attribute Directive
   - Custom Structural Directive
4. Practical Examples
5. Conclusion

### 1. What are Angular Directives?

Angular directives are special tokens in the markup that tell the Angular compiler to do something with a DOM element or even the entire DOM tree. They play a crucial role in extending the HTML vocabulary and making it more expressive.

### 2. Types of Directives

Angular directives can be categorized into three main types:

#### Attribute Directives

Attribute directives are used to change the appearance or behavior of an element, component, or another directive. They are typically applied as attributes to elements.

**Example: `ngClass`**

```html
<div [ngClass]="{'highlight': isHighlighted}">Hello, Angular!</div>
```

#### Structural Directives

Structural directives change the DOM layout by adding or removing elements. They are denoted by a leading asterisk (`*`).

**Example: `ngIf`**

```html
<div *ngIf="isVisible">This content is conditionally visible.</div>
```

#### Component Directives

Component directives are the most common directives in Angular. Every component you create is a directive with a template.

**Example: Custom Component**

```typescript
@Component({
  selector: 'app-greeting',
  template: `<h1>Hello, {{name}}!</h1>`
})
export class GreetingComponent {
  name: string = 'Angular';
}
```

### 3. Creating Custom Directives

Creating custom directives in Angular is straightforward. Let's explore how to create both attribute and structural directives.

#### Custom Attribute Directive

We'll create an attribute directive that changes the background color of an element when it is hovered over.

**Step 1: Generate the Directive**

```bash
ng generate directive hoverHighlight
```

**Step 2: Implement the Directive**

```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(null);
  }

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

**Step 3: Use the Directive in a Template**

```html
<p appHoverHighlight highlightColor="lightblue">Hover over me to see the effect!</p>
```

#### Custom Structural Directive

We'll create a structural directive that conditionally includes a template based on a boolean expression.

**Step 1: Generate the Directive**

```bash
ng generate directive ifNot
```

**Step 2: Implement the Directive**

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

@Directive({
  selector: '[appIfNot]'
})
export class IfNotDirective {
  @Input() set appIfNot(condition: boolean) {
    if (!condition) {
      this.viewContainer.createEmbeddedView(this.templateRef);
    } else {
      this.viewContainer.clear();
    }
  }

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

**Step 3: Use the Directive in a Template**

```html
<div *appIfNot="isVisible">This content is conditionally hidden.</div>
```

### 4. Practical Examples

Let's put everything together with a practical example. We will create an Angular application that uses both custom attribute and structural directives.

**Step 1: Create a New Angular Application**

```bash
ng new directive-demo
cd directive-demo
```

**Step 2: Create Directives (ifNot and hoverHighlight)**

Follow the steps above to generate and implement `HoverHighlightDirective` and `IfNotDirective`.

**Step 3: Update the App Component**

**app.component.html:**

```html
<h1>Angular Directive Demo</h1>
<p appHoverHighlight highlightColor="lightgreen">Hover over this text to see the background color change.</p>
<button (click)="toggleVisibility()">Toggle Visibility</button>
<div *appIfNot="isContentVisible">This content is conditionally hidden.</div>
```

**app.component.ts:**

```typescript
import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.css']
})
export class AppComponent {
  isContentVisible: boolean = true;

  toggleVisibility() {
    this.isContentVisible = !this.isContentVisible;
  }
}
```

[Stackblitz Link](https://stackblitz.com/edit/stackblitz-starters-sdgf7s?file=src%2Fmain.ts)

### 5. Conclusion

Angular directives are powerful tools for extending HTML's capabilities and building dynamic, interactive applications. By understanding and utilizing attribute, structural, and component directives, you can create more modular and reusable code. Custom directives further enhance your ability to create tailored behaviors and improve the overall user experience.

Experiment with creating your own directives to see how they can simplify and enrich your Angular projects. Happy coding!