Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to dynamically add a directive?

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

like image 790
RichieRock Avatar asked Dec 23 '16 08:12

RichieRock


People also ask

How do you do a conditional directive?

Currently, there is NO way to conditionally apply a directive to a component. This is not supported. The components which you have created can be added or removed conditionally. There is already an issue created for the same with angular2 , so it should be the case with angular4 aswell.

How do you create a directive?

To create a directive, use the CLI command ng generate directive . The CLI creates src/app/highlight. directive. ts , a corresponding test file src/app/highlight.

Can a directive have input?

If we also specify an input property in our directive's class using the same value as the selector property value we can input data into our directive using the attribute on the host element. This instructs Angular that the appBtnGrow class member property is now an input that can receive a value from the host element.

What are dynamic angular components?

Dynamic component loadinglink This makes it impractical to use a template with a static component structure. Instead, you need a way to load a new component without a fixed reference to the component in the ad banner's template. Angular comes with its own API for loading components dynamically.


1 Answers

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();
    }
}
like image 115
coderdark Avatar answered Oct 19 '22 10:10

coderdark