Angular - The Ultimate Walkthrough Learning Guide
What do you need to learn to become an Angular Master? The journey can feel overwhelming. The YouTube series can feel like it’s only covering the basics. That’s why I’ve created this Walkthrough Learning Guide to help you get started on your Angular journey. From zero to pro, these articles

Angular, as one of the predominant web application frameworks, offers developers a plethora of tools and features to architect efficient and interactive user interfaces. Among these, directives stand out as powerful instruments to manipulate and extend the behavior of HTML elements in our templates. While Angular ships with a variety of built-in directives, the true potential unfolds when developers dive into creating custom directives tailored to specific application needs. Such customizations offer finer control, enhanced reusability, and a more semantic template structure.

This tutorial delves deep into the world of Angular directives, transcending beyond the basics, and exploring the creation and utilization of advanced custom directives. By understanding their underlying principles and mechanisms, you'll be poised to craft versatile UI enhancements that truly elevate the user experience.

Learning Outcomes:

By the end of this tutorial, you will:

  • Understand the various lifecycle hooks associated with directives.
  • Be able to create custom directives tailored for your Angular applications.
  • Master advanced directive techniques such as host binding, host listeners, and the use of inputs.

Prerequisites:

To ensure a seamless learning experience, it's beneficial if you:

  • Have a foundational knowledge of Angular and its core concepts.
  • Are familiar with TypeScript and modern JavaScript ES6+ features.
  • Have prior experience or at least familiarity with basic Angular directives.

With these prerequisites in mind, gear up to unlock the next level of Angular development with custom directives!

Lifecycle Hooks in Angular Directives

Introduction to Lifecycle Hooks and Their Significance

Lifecycle hooks are a powerful feature in Angular that allow you to tap into specific moments in the lifecycle of a directive or component. They are functions that Angular calls at specific points during the lifecycle, from creation to destruction, of a directive or component. These hooks provide visibility into these key life moments and the ability to act when they occur.

Comparison of Component Lifecycle Hooks vs Directive Lifecycle Hooks

Both components and directives in Angular have lifecycle hooks, but they are used in slightly different ways.

Components have more lifecycle hooks than directives. This is because components have a template associated with them which needs to be rendered and checked, whereas directives do not. Therefore, hooks related to component initialization (ngOnInit), change detection (ngOnChanges, ngDoCheck), content and view initialization (ngAfterContentInit, ngAfterViewInit), and their respective “after checked” hooks (ngAfterContentChecked, ngAfterViewChecked) can be used with both components and directives.

However, hooks related to view rendering such as ngAfterViewInit and ngAfterViewChecked are specific to components as they deal with the component’s view that gets rendered.

Deep Dive into Directive-Specific Hooks like ngOnInit, ngOnChanges, ngOnDestroy, etc.

Let’s take a closer look at some of the key lifecycle hooks that can be used in directives:

  • ngOnInit: This hook is called once after the directive’s data-bound properties have been initialized. It is a good place to put initialization code for your directive.
import { Directive, OnInit } from '@angular/core';

@Directive({ selector: '[myDirective]' })
export class MyDirective implements OnInit {
  ngOnInit() {
    console.log('Directive Initialized');
  }
}
  • ngOnChanges: This hook is called whenever one of the directive’s data-bound input properties changes. The hook receives a SimpleChanges object containing the previous and current values of the property.
import { Directive, Input, OnChanges, SimpleChanges } from '@angular/core';

@Directive({ selector: '[myDirective]' })
export class MyDirective implements OnChanges {
  @Input() myProperty: string;

  ngOnChanges(changes: SimpleChanges) {
    console.log('Changes', changes);
  }
}
  • ngOnDestroy: This hook is called just before Angular destroys the directive. This is a good place to clean up any resources that the directive is holding onto.
import { Directive, OnDestroy } from '@angular/core';

@Directive({ selector: '[myDirective]' })
export class MyDirective implements OnDestroy {
  ngOnDestroy() {
    console.log('Directive Destroyed');
  }
}

Remember that these hooks are called automatically by Angular when appropriate, so you don’t need to call them yourself. You just need to implement them in your directive class.

Basics of Creating Custom Directives

Setting the Groundwork: Why Custom Directives?

Custom directives in Angular allow you to create reusable components with encapsulated behavior. They provide a way to extend the functionality of HTML elements, giving you the power to create more expressive and readable code. Custom directives can help reduce code duplication, increase readability, and make your code more maintainable.

Anatomy of a Custom Directive in Angular

A custom directive in Angular is essentially a class decorated with the @Directive decorator. The @Directive decorator takes a configuration object that can have properties like selector (to specify the CSS selector that identifies the directive), inputs (to define input bindings), and outputs (to define output bindings).

Here’s a basic structure of a custom directive:

import { Directive } from '@angular/core';

@Directive({
  selector: '[myCustomDirective]'
})
export class MyCustomDirective {
  // Directive logic goes here
}

Building a Simple Custom Directive: A Step-by-Step Example

Let’s create a simple custom directive that changes the background color of an element when the user hovers over it.

  1. Create the Directive File: First, create a new file for your directive. You might name it highlight.directive.ts.
  2. Import Necessary Modules: Import the necessary Angular modules in your directive file.
import { Directive, ElementRef, HostListener } from '@angular/core';

3. Define the Directive: Next, define your directive class and use the @Directive decorator to configure it.

@Directive({
  selector: '[appHighlight]'
})
export class HighlightDirective {
  constructor(private el: ElementRef) { }
}

4. Add Event Handlers: Use the @HostListener decorator to add event handlers for mouse enter and leave events.

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

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

5. Define the Highlight Method: Finally, define the method that changes the background color of the host element.

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

Now you can use your custom directive in your Angular templates like so:

<p appHighlight>Hover over me!</p>

When you hover over this paragraph, it will be highlighted in yellow, and when you move your mouse away, the highlight will be removed.

Using @Input in Directives

The @Input decorator in Angular is used to bind a property within one child component/directive to receive a value from its parent component. It’s a way of passing data from the parent component to the child component/directive. This is particularly important in directives, as it allows us to create more dynamic and reusable directives.

Passing Data to a Directive Using @Input

This post is for paying subscribers only

Sign up now and upgrade your account to read the post and get access to the full library of posts for paying subscribers only.

Sign up now Already have an account? Sign in