Angular Reusable Loading Component Using Directive

We will create a common directive first with @Input property to receive true or false conditionally to add and remove the CSS class accordingly, as we use the directive to extend the HTML functionality.

Sometimes, we need reusable components which you develop once and use anywhere without any additional change.
 
Let's start. We will create a common directive first with @Input property to receive true or false conditionally to add and remove the CSS class accordingly, as we use the directive to extend the HTML functionality.
 
Step 1
 
Create a Directive with Angular CLI (ng g d dir_name),
  1. import { Directive, ElementRef, Input, OnChanges, Renderer2 } from '@angular/core';  
  2. import { LoaderSyncService } from './loader-sync.service';  
  3.   
  4. @Directive({  
  5.   // tslint:disable-next-line:directive-selector  
  6.   selector: '[drloader]'  
  7. })  
  8. export class LoaderDirective implements OnChanges {  
  9.     @Input('drloader') drloader: boolean;  
  10.     constructor(private el: ElementRef, private loader: LoaderSyncService, private renderer: Renderer2) { }  
  11.   
  12.         ngOnChanges() {  
  13.                if (this.drloader) {  
  14.                 const parent = this.renderer.parentNode(this.el.nativeElement);  
  15.                 const div = this.renderer.createElement('div');  
  16.                 this.renderer.addClass(div, 'divshow');  
  17.                 // tslint:disable-next-line:label-position  
  18.                 const ispan: Element = this.renderer.createElement('i');  
  19.                 this.renderer.addClass(ispan, 'fa');  
  20.                 this.renderer.addClass(ispan, 'fa-spinner');  
  21.                 this.renderer.addClass(ispan, 'fa-spin');  
  22.                 this.renderer.addClass(ispan, 'center');  
  23.                 this.renderer.addClass(ispan, 'loder-icon');  
  24.                 this.el.nativeElement.parentElement.classList.add('positionReletive');  
  25.                 const finalhtml = this.renderer.appendChild(div, ispan);  
  26.                 this.renderer.appendChild(this.el.nativeElement, div);  
  27.             } else {  
  28.                    Array.from(this.el.nativeElement.children).forEach(child => {  
  29.                     if (child['className'] === 'divshow') {  
  30.                                     this.renderer.removeChild(this.el.nativeElement, child);  
  31.                     }  
  32.                 });  
  33.             }  
  34.         }  
  35. }  
Step 2
 
Add CSS class definition which will help us to use it in any size HTML element,
  1. .center {  
  2.     marginauto;  
  3.     margin-left:  680px;  
  4. }  
  5.   
  6. .loder-icon {  
  7.     positionabsolute;  
  8.     font-size54px;  
  9.     colorred;  
  10.     left: 50%;  
  11.     top:50%;  
  12.     margin-top-20px;  
  13.     margin-left-20px;  
  14. }  
  15.   
  16. .positionReletive {  
  17.       width:100%;position:relative;  
  18. }  
  19.   
  20. .divshow {  
  21.     displayblock;  
  22. }  
  23.   
  24. .divhide {  
  25.     displaynone;  
  26. }  

Step 3

Use the custom directive in to HTML with isLoader=true and false below,
  1. <div style="width:100%;" class="bd">  
  2.            <h3 [drloader]="isLoader">My content with width:100% :     
  3.                {{tempData | json}}  
  4.           </h3>  
  5. </div>  
  6.   
  7. <div style="width:50%;" class="bd">  
  8.            <h3 [drloader]="isLoader">My content with width:50% :     
  9.                {{tempData | json}}  
  10.           </h3>  
  11. </div>  
  12.   
  13. <div style="width:25%;" class="bd">  
  14.            <h3 [drloader]="isLoader">My content :     
  15.                {{tempData | json}}  
  16.            </h3>  
  17. </div>  
Step 4
 
Let's check the output with 100% and 50% width div's. No matter what the div size is the loader icon will display at the center of div content.
 
Angular Reusable Loading Component Using Directive