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. @Directive({
  4. // tslint:disable-next-line:directive-selector
  5. selector: '[drloader]'
  6. })
  7. export class LoaderDirective implements OnChanges {
  8. @Input('drloader') drloader: boolean;
  9. constructor(private el: ElementRef, private loader: LoaderSyncService, private renderer: Renderer2) { }
  10. ngOnChanges() {
  11. if (this.drloader) {
  12. const parent = this.renderer.parentNode(this.el.nativeElement);
  13. const div = this.renderer.createElement('div');
  14. this.renderer.addClass(div, 'divshow');
  15. // tslint:disable-next-line:label-position
  16. const ispan: Element = this.renderer.createElement('i');
  17. this.renderer.addClass(ispan, 'fa');
  18. this.renderer.addClass(ispan, 'fa-spinner');
  19. this.renderer.addClass(ispan, 'fa-spin');
  20. this.renderer.addClass(ispan, 'center');
  21. this.renderer.addClass(ispan, 'loder-icon');
  22. this.el.nativeElement.parentElement.classList.add('positionReletive');
  23. const finalhtml = this.renderer.appendChild(div, ispan);
  24. this.renderer.appendChild(this.el.nativeElement, div);
  25. } else {
  26. Array.from(this.el.nativeElement.children).forEach(child => {
  27. if (child['className'] === 'divshow') {
  28. this.renderer.removeChild(this.el.nativeElement, child);
  29. }
  30. });
  31. }
  32. }
  33. }
Step 2
Add CSS class definition which will help us to use it in any size HTML element,
  1. .center {
  2. margin: auto;
  3. margin-left: 680px;
  4. }
  5. .loder-icon {
  6. position: absolute;
  7. font-size: 54px;
  8. color: red;
  9. left: 50%;
  10. top:50%;
  11. margin-top: -20px;
  12. margin-left: -20px;
  13. }
  14. .positionReletive {
  15. width:100%;position:relative;
  16. }
  17. .divshow {
  18. display: block;
  19. }
  20. .divhide {
  21. display: none;
  22. }

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. <div style="width:50%;" class="bd">
  7. <h3 [drloader]="isLoader">My content with width:50% :
  8. {{tempData | json}}
  9. </h3>
  10. </div>
  11. <div style="width:25%;" class="bd">
  12. <h3 [drloader]="isLoader">My content :
  13. {{tempData | json}}
  14. </h3>
  15. </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
Get Complete Code