How to dynamically add a directive?

AngularTypescriptAngular2 Directives

Angular Problem Overview


How to dynamically add (inject) a directive into host?

I have a myTooltip directive and I would like to add mdTooltip directive to it's host. I have tried setAttribute() of ElementRef.nativeElement, but it doesn't create the mdTooltip directive.

mytooltip.directive.ts:

@Directive({
  selector: '[my-tooltip]',
  host: {
    '(mouseenter)': 'show()',
    '(mouseleave)': 'hide()',
  }
})
export class myTooltip {
  @Input('my-tooltip') message;

  constructor() { }

  show() {
    /* TODO: How to add md-tooltip directive to elementref (host)? */
  }

  hide() {
    /* TODO: remove md-tooltip directive from elementref (host) */
  }
}

By host I mean the element that has myTooltip directive:

<span my-tooltip="tooltip hint">Click here</span>

The result wouldn't change above html but on mouseenter it would have md-tooltip directive in span.

BTW, the reason I am using a wrapper and not directly md-tooltip is that I want to later modify the showing delay, hiding delay and customize material tooltip's behaviour in other means as well.

Edit Apparently adding directives dynamically is not currently supported :( I think this question should still be here in case it material team updates that

Angular Solutions


Solution 1 - Angular

That is a feature we are asking for in angular...read this: https://github.com/angular/angular/issues/8785

A quick and dirty way to do it is to use:

I have a directive named myHilite (to highlight text), I also have a component named MainComponent.ts. In MainComponent.ts I added this line of code...

export class MainComponent {
    @HostBinding('attr.myHilite') myHiliteDirective = new myHilite();
} 

If your directive requires parameters...

export class MainComponent {
    @HostBinding('attr.myHilite') myHiliteDirective = new myHilite(this.elementRef);
}

Your directive may need to execute code in one of its life cycle hooks, manually call the directive's lifecycle hook method in the parent component's lifecycle hook method like this...

export class MainComponent {
    //...code...

    ngOnInit(){
        this.myHiliteDirective.ngOnInit();
    }
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionRichieRockView Question on Stackoverflow
Solution 1 - AngularcoderdarkView Answer on Stackoverflow