Angular 9|8|7 Convert Directive into Shared to use in Feature Modules

In this tutorial, we will learn how to create custom Directive in Angular Application and re-use them in different components and at different levels of module hierarchy.

Sometimes in large Angular applications, we may have a more complex structure of components where some of them may have their own feature modules and sub-modules or components.

In that case, it becomes a little tricky to use some reusables at different levels at parent-child structures. Here we will create a new Angular project with a similar type of component structure with a parent-child structure to teach how we can use directive with a simple trick

How to use a custom Directive in multiple modules and it’s components?

To make a directive available at all places, we need to create its own module to import and export it.

Sounds weird?

Let’s create a  simple directive which will add an asterisk(*) sign to required fields:

 

requiredsign.directive.ts 

// requiredsign.directive.ts
import { Directive, OnInit, ElementRef, Renderer2, NgModule } from '@angular/core';

@Directive({
  selector: '[required]'
})
export class RequiredsignDirective implements OnInit {

  constructor(private renderer: Renderer2, private el: ElementRef) {}

  ngOnInit() {
    const parent = this.renderer.parentNode(this.el.nativeElement);
    if (parent.getElementsByTagName('LABEL').length) {
      parent.getElementsByTagName('LABEL')[0].innerHTML += '<span class="required-asterisk">*</span>';
    }
  }
}

 

In addition to the above code for the directive, we will also add its own module with export and import properties having this directive:

...
...
@NgModule({
  declarations: [ RequiredsignDirective ],
  exports: [ RequiredsignDirective ]
})

export class RequiredsignDirectiveModule {}

 

So now our complete directive will look like this:

// requiredsign.directive.ts
import { Directive, OnInit, ElementRef, Renderer2, NgModule } from '@angular/core';

@Directive({
  selector: '[required]'
})
export class RequiredsignDirective implements OnInit {

  constructor(private renderer: Renderer2, private el: ElementRef) {}

  ngOnInit() {
    const parent = this.renderer.parentNode(this.el.nativeElement);
    if (parent.getElementsByTagName('LABEL').length) {
      parent.getElementsByTagName('LABEL')[0].innerHTML += '<span class="required-asterisk">*</span>';
    }
  }
}

@NgModule({
  declarations: [ RequiredsignDirective ],
  exports: [ RequiredsignDirective ]
})

export class RequiredsignDirectiveModule {}

 

Where and How to use this Directive?

Now if we create a simple custom directive, it is added in declarations array of the app.module.ts file, but as we have a complex modular structure of the project as shown below:

So instead of adding RequiredsignDirective in declarations array, we will add RequiredsignDirectiveModule in imports array as shown below:

// add-user.module.ts 
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { AddUserComponent } from './add-user.component';
import { FormsModule, ReactiveFormsModule } from '@angular/forms';
import { UseraccessService } from '../http/useraccess.service';
import { RequiredsignDirectiveModule } from 'src/app/shared/directives/requiredsign.directive';

@NgModule({
    imports: [
        CommonModule,
        FormsModule,

        RequiredsignDirectiveModule
    ],
    declarations: [AddUserComponent],
    providers: [
      UseraccessService
    ]
})
export class AddUserModule {}

That’s it now your directive will work as expected as its class is available for import and export using its own module anywhere in the project.

 

So here we got to know how we can convert a simple custom Directive into a module to be added anywhere in the project by simply adding its own @NgModule decorator.

 

1 thought on “Angular 9|8|7 Convert Directive into Shared to use in Feature Modules”

Leave a Comment

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