23

I've seen two questions here how to conditionally add and remove attributes on an item (Is it possible to conditionally display element attributes using Angular2?) but my question is if it is possible to add and remove attribute directives ? I am able to add and remove the attribute but Angular does not "compile" the attribute as an attribute directive but the attribute just sits there doing nothing. Here is an example of 2 tags:

The first one is the one that I am trying to conditionally apply the attribute directive and the second one has it all the time.

Here is the gif: enter image description here

Here is how I am applying the attribute (maybe there is a different way to apply attribute directive?)

<h1 [attr.colored]="check ? '': null">Testing something</h1>

And here is the directive:

import {Directive, ElementRef} from '@angular/core'
@Directive({
    selector: '[colored]',
    host: {
        '(mouseenter)': 'onMouseEnter()',
        '(mouseleave)': 'onMouseLeave()'
    }
})

export class colorDirective {
    constructor(private el: ElementRef) {
    }
    onMouseEnter() { this.highlight("yellow"); }
    onMouseLeave() { this.highlight(null); }

    private highlight(color: string) {
        this.el.nativeElement.style.backgroundColor = color;
    }
}

Edit: There are couple answers but they are for AngularJS (1)

Community
  • 1
  • 1
Denko Mancheski
  • 2,709
  • 2
  • 18
  • 26

4 Answers4

8

That is not supported. Directives are only applied when static HTML matches the selector.

Günter Zöchbauer
  • 623,577
  • 216
  • 2,003
  • 1,567
1

I know this is a late reply, but might help someone.

You can pass a condition as an input to the attribute directive,

<h1 colored [enable]="check">Testing something</h1>

and then in the directive

    import {Directive, ElementRef} from '@angular/core'

@Directive({
    selector: '[colored]',
    host: {
        '(mouseenter)': 'onMouseEnter()',
        '(mouseleave)': 'onMouseLeave()'
    }
})
        
export class colorDirective {
    
    @Input() enable: boolean = true;

    constructor(private el: ElementRef) {
    }
    onMouseEnter() { 
        if(this.enable){
            this.highlight("yellow");  
        }
    }   

    onMouseLeave() { 
        if(this.enable){
            this.highlight(null); 
        }
    }

    private highlight(color: string) {
        this.el.nativeElement.style.backgroundColor = color;
    }
}
        

 
0

You could pass a flag to the directive

In directive:

ngAfterViewInit()
{
  let tooltip = this.tooltip instanceof Object ? this.tooltip : {disabled: this.tooltip};
  if (!tooltip.disabled) {
    //DO STUFF
  }
}

In DOM:

<span [tooltip]="{disabled: true}"></span>
-1

So before you could have a component recompile it's own $scope with $compile() but it isn't in angular2. You can compile at runtime a NEW component, here's a good SO with a few ways with dynamicComponentLoader: Equivalent of $compile in Angular 2

And another: Angular 2 equivalent of ng-bind-html, $sce.trustAsHTML(), and $compile?

The question I have is what is the use-case of toggling directives? I can't think of why I would but I'm curious what your need is.. For most things ngIf, ngSwitch, etc. work for me while toggling..

Community
  • 1
  • 1
Dennis Smolek
  • 8,480
  • 7
  • 30
  • 39
  • Here's my use case: I'm using Bootstrap. I created a component for text inputs so that I don't have to create the wrapper div (`.form-group`) and the label for the text input, and can instead just use one line for each text input, passing the label as an `@Input()` to the component. I have also created a CurrencyDirective to format the input as currency. Now I want to be able to set that directive on one of my text inputs, but I would have to pass a flag into the text input component that indicates whether or not the directive should be added to the `` element in the component. – Travesty3 Oct 07 '16 at 13:32