Angular Custom Directives – A Practical Guide For Angular Developers

nangular-custom-directive-with-example-code

n
nIn this article, I am going to dive deep into what angular directives are and how you can build your own.
n
n

nOverview

nAngular Directives are of three kinds:
nComponents, Structural and Attribute Directives e.g NgIf. Component directives are directive with a template while structural as the name implies are used to change the structure of the DOM by adding and removing elements from the DOM.
nnnnnAttribute directives is used to extend the behavior of component, an element or even another directives.
n
n

nBuild a simple Attribute directive

nBuilding a directive in Angular is as simple as decorating a class with Directive and add metadata like so:
n
n

import {Directive} from '@angular/core';nn@Directive({n  selector: '[greetings-directive]',n})nexport class GreetingsDirective {n...n}nn

nThe next thing is to tell angular that we have a directive named GreetingsDirective by adding it to the declarations array in the AppModule like so:nn
n

declarations: [n AppComponent,n GreetingsDirectiven],nn

nNow our GreetingsDirective is ready to be used in our application. Note that a directive must belong to one and only one NgModule.
n
nUsing the directive is as simple as adding the selector to an element as attribute like so:n
n

nGreeting Directive

n

nIn the above code, the h3 tag is called the host element of the directive.nn
n
n

nInteracting with the Host

nLet’s say we want to change the innerHTML of the host element, in this case the h3 tag, we can do that by importing the ElementRef symbol from the Angular core library, and the inject it to the directive’s constructor like so:
n

import { Directive, ElementRef } from "@angular/core";nn@Directive({n  selector: "[greetings-irective]"n})nexport class GreetingsDirective {n  constructor(elem: ElementRef) {n    elem.nativeElement.innerHTML = "Hello Directive";    n  }n}n

nAs you can see, the ElementRef gave the directive a direct and full access to the host element – that is the element upon which the directive is attached. This will change the text of the the h3 tag to Hello Directive.
nnn
nnn

nBinding host element event with directive

nIn order to bind the directive to a host’s click event, we’re going to use the decoratornHostListener.
nThe hostlistener allows a directive to listen to events on its host element. We’ll do this by decorating a function on the component with the @HostListener() decoration.n
n
nIn this example let’s listen to the click event on the host element, we will do this by adding @HostListener(‘click’) on the function method we want to call when the host is clicked like so:
n

import { Directive, ElementRef, HostListener } from "@angular/core";nn@Directive({n  selector: "[greetings-irective]"n})nexport class GreetingsDirective {n  constructor(elem: ElementRef) {n    elem.nativeElement.innerHTML = "Hello Directive";n  }nn  @HostListener("click")   showGreetingAlert(): void {n    alert("Hello Directive");n  }n}nn

n
n
nNow when the host is clicked, the showGeetingAlert function will be called and we will get an alert saying Hello Directive.
n
n

nCreating a Simple Directive to Convert Text to Title Case

nLet’s build an attribute directive that will change it host element value text to title case. After building the directive, we can then simply add it to an input element like so:
n

n

n

nSetup the Directive using Angular CLI

nWe are going to create a new directive using angular cli like so
n

ng generate directive directive/titleCasen

n
nThe above command will generate our directive within a folder named directive within the app folder and also include the directive in the declaration section in the app module.n
n
nOur src/app directory will now look like this:
n
nsrc/app/directive
n
n

nBringing our directive to live

nOpen up title title-case.directive.spec.ts
n
nThe first thing we need to do is to change the selector from appTitleCase to app-title-case like so
n

@Directive({n  selector: '[app-title-case]'n})n

n
nThe second step is to inject ElementRef which will give the directive full access to the host element.nnOur directive should like so after ElementRef injectionn
n

import { Directive, ElementRef } from '@angular/core';nn@Directive({n  selector: '[app-title-case]'n})nexport class TitleCaseDirective {nn  elemRef :ElementRef;n  constructor(private el:ElementRef) { n    this.elemRef =el;n  }nn}n

n
nNext we need a way to listen to the host element event by bringing in HostListener like so:nnn
nnn

@HostListener('focusout') onfocusOut(){ }nnn

n
nAs you can see we want to listen to the focusout event of the host element and then do the conversion. We will use regular expression to convert the text to title case like so:
n

toTitleCase(input){n    return input.replace(/\w\S*/g, (txt => txt[0].toUpperCase() + txt.substr(1).toLowerCase() ));n  }n

n
n

nThe Directive Complete Codenn

n

import { Directive, ElementRef, HostListener } from '@angular/core';nn@Directive({n  selector: '[app-title-case]'n})nexport class TitleCaseDirective {nn  elemRef :ElementRef;n  constructor(private el:ElementRef) { n    this.elemRef =el;n  }nn  @HostListener('focusout') onfocusOut(){    n    this.elemRef.nativeElement.value= this. toTitleCase(this.elemRef.nativeElement.value);n  }nn  toTitleCase(input){n    return input.replace(/\w\S*/g, (txt => txt[0].toUpperCase() + txt.substr(1).toLowerCase() ));n  }nn}n

n
nWe listen to to the focusout of the host element and the access the value using ElementRef, convert it to title case and then update the value with the result.nnOur directive is now ready to be used in our application.nnHappy Coding!

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top