Many of angular developers who has experience in angularJs would be familar of adding directives dynamically using $compile service. If you are expecting the same feature in angular framework, then simple answer is NO

Angular doesn’t expose $compile service to recompile your template and when you add attribute to DOM elements, angular wouldn’t recognize even though attribute is part of angular directive.

There are few workaround to add directive dynamically, Let me walk through those ways

1.) Using angular structural directive *ngIf

Let’s assume we have directive name “tooltip” and we wanted to attach only on certain condition. For this situation we can use *ngIf. ngIf directive will remove element from DOM when condition is false and it will create an element, compile and attach to DOM when condition is true.

<a *ngIf="showTooltip" [tooltip]="This is dynamic tooltip">Need Help?</a>

2.) Creating new directive instance 

Let’s assume we have button directive and we wanted to add this directive to element dynamically

Here is the simple button directive code snippet

@Directive({ selector: '[appButton]' })
export class ButtonDirective implements AfterViewInit {

    @Input() appButton: string;

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

    ngAfterViewInit(): void {
        this.renderer.addClass(this.elementRef.nativeElement, 'ui');
        this.renderer.addClass(this.elementRef.nativeElement, 'button');
        this.renderer.addClass(this.elementRef.nativeElement, this.appButton);
    }
}

We wanted to add this button directive dynamically to element.

<button type="button" #actionBtn> Done </button>
Plain Button
Plain Button without directive
export class TopNavComponent implements AfterViewInit {

     @ViewChild('actionBtn') actionBtnRef: ElementRef;

     constructor(private renderer: Renderer2) { }

     ngAfterViewInit() {
     const btnDirective = new ButtonDirective(this.actionBtnRef, 
     this.renderer);
           btnDirective.appButton = 'green';
           btnDirective.ngAfterViewInit();
    }
}
Green Button
After applying button directive

To create new instance of button directive we need couple of arguments, 1st argument is ElementRef and 2nd argument is Renderer2

I have a template variable actionBtn, using ViewChild decorator i can get elementRef and i have rendere initialized in constructor.

Since we are explicity creating an instance, its our responsibility to assign input values and kick of life cycle methods.

Categories: Angular

Leave a Reply

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

This site uses Akismet to reduce spam. Learn how your comment data is processed.