Aplicar una directiva condicionalmente


Estoy usando el Material 2 para agregar md-raised-button.

Quiero aplicar esta directiva solo si se cumple una condición determinada.

Por ejemplo:

<button md-raised-button="true"></button>

Otro ejemplo: Creé una forma reactiva dinámica básica en plunker. Estoy usando formArrayName directiva de forma reactiva para la matriz de controles. Quiero aplicar la directiva formArrayName solo si la condición específica se cumple. de lo contrario, no agregue la directiva formArrayName. Intenté e investigué mucho, pero pude encontrar cualquier solución.

Aquí está enlace del émbolo: https://plnkr.co/edit/oPZ7PyBSf8jjYa2KVh4J?p=preview

Realmente agradecería cualquier contribución.

Gracias de antemano!

Author: Alexander Abakumov, 2017-06-16

11 answers

No se si puede aplicar directivas basadas en una condición, pero una solución tendría 2 botones y los mostraría basados en una condición.

<button *ngIf="!condition"></button>
<button *ngIf="condition" md-raised-button></button> 

Editar: tal vez esto será útil.

 20
Author: LLL,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-11-30 14:48:43

Puede utilizar el siguiente método:

<button [attr.md-raised-button]="condition ? '' : null"></button>

Aplicó lo mismo a su émbolo: tenedor

Actualización:

Cómo funciona condition ? '' : null como el valor:

Cuando su cadena vacía ('') se convierte en attr.md-raised-button="", cuando su null el atributo no existirá.

 23
Author: Aldracor,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-05-09 14:46:11

Como otros también han dicho, directives no se puede aplicar dinámicamente.

Sin embargo, si solo desea cambiar el estilo de md-button de plano a elevado , entonces esto

<button md-button [class.mat-raised-button]="isRaised">Toggle Raised Button</button>

Haría el truco. Plunker

 5
Author: Ankit Singh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-06-21 04:32:53

Como ya se ha señalado, esto no parece ser posible. Una cosa que se puede usar para al menos evitar alguna duplicación es ng-template. Esto le permite extraer el contenido del elemento afectado por la ramificación ngIf.

Si, por ejemplo, desea crear un componente de menú jerárquico utilizando Angular Material:

<!-- Button contents -->
<ng-template #contentTemplate>
    <mat-icon *ngIf="item.icon != null">{{ item.icon }}</mat-icon>
    {{ item.label }}
</ng-template>

<!-- Leaf button -->
<button *ngIf="item.children == null" mat-menu-item
    (click)="executeCommand()"
    [disabled]="enabled == false">
    <ng-container *ngTemplateOutlet="contentTemplate"></ng-container>
</button>
<!-- Node button -->
<ng-container *ngIf="item.children != null">
    <button mat-menu-item
        [matMenuTriggerFor]="subMenu">
        <ng-container *ngTemplateOutlet="contentTemplate"></ng-container>
    </button>

    <mat-menu #subMenu="matMenu">
        <menu-item *ngFor="let child of item.children" [item]="child"></menu-item>
    </mat-menu>
</ng-container>

Aquí la directiva aplicada condicionalmente es matMenuTriggerFor, que solo debe aplicarse a elementos de menú con hijos. El contenido del botón se inserta en ambos places via ngTemplateOutlet.

 5
Author: H.B.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-01-04 02:31:24

Esto puede llegar tarde, pero es un método viable y elegante para aplicar una directiva condicionalmente.

En la clase directiva cree la variable de entrada:

@Input('myDirective') options: any;

Al aplicar la directiva, establezca la propiedad apply de la variable de entrada:

<div [myDirective] = {apply: someCondition}></div>

En el método de la directiva compruebe la variable this.opcion.aplicar y aplicar la lógica directiva basada en la condición:

ngAfterViewInit(): void {
    if (!this.options.apply) {
        return;
    }

    // directive logic
}
 4
Author: Tiha,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-01-29 08:38:03

Actualmente, hay NO forma de aplicar condicionalmente una directiva a un componente.Esto no es compatible.Los componentes que ha creado se pueden agregar o eliminar condicionalmente.

Ya hay un problema creado para el mismo con angular2, así que debería ser el caso con angular4 también.

Alternativamente, puede optar por la opción con ng-if

<button ngIf="!condition"></button>
<button ngIf="condition" md-raised-button></button> 
 3
Author: Sajeetharan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-06-19 18:16:29

Sí es posible.

Página html con la directiva appActiveAhover:)

  <li routerLinkActive="active" #link1="routerLinkActive">
        <a [appActiveAhover]='link1.isActive?false:true' routerLink="administration" [ngStyle]="{'background':link1.isActive?domaindata.get_color3():none}">
          <i class="fa fa-users fa-lg" aria-hidden="true"></i> Administration</a>
      </li>
      <li  routerLinkActive="active" #link2="routerLinkActive">
        <a [appActiveAhover]='link2.isActive?false:true' routerLink="verkaufsburo" [ngStyle]="{'background':link2.isActive?domaindata.get_color3():none,'color':link2.isActive?color2:none}">
          <i class="fa fa-truck fa-lg" aria-hidden="true"></i> Verkaufsbüro</a>
      </li>
      <li  routerLinkActive="active" #link3="routerLinkActive">
        <a [appActiveAhover]='link3.isActive?false:true' routerLink="preisrechner" [ngStyle]="{'background':link3.isActive?domaindata.get_color3():none}">
          <i class="fa fa-calculator fa-lg" aria-hidden="true" *ngIf="routerLinkActive"></i> Preisrechner</a>
      </li>

Directiva

@Directive({
  selector: '[appActiveAhover]'
})
export class ActiveAhoverDirective implements OnInit {
  @Input() appActiveAhover:boolean;
  constructor(public el: ElementRef, public renderer: Renderer, public domaindata: DomainnameDataService) {
}

  ngOnInit() {
  }

  @HostListener('mouseover') onMouseOver() {
    if(this.appActiveAhover){
      this.renderer.setElementStyle(this.el.nativeElement, 'color', this.domaindata.domaindata.color2);
    }
  }

  @HostListener('mouseout') onMouseOut() {
    if(this.appActiveAhover){
      this.renderer.setElementStyle(this.el.nativeElement, 'color', 'white');
    }
  }

}
 2
Author: Chaitanya Nekkalapudi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-11-22 09:20:31

Esto también podría ser una solución:

[md-raised-button]="condition ? 'true' : ''"


Funciona para angular 4, ionic 3 así:

[color]="condition ? 'primary' : ''" donde condition es una función que decide si esta es una página activa o no. Todo el código se ve así:

<button *ngFor="let page of ..." [color]="isActivePage(page) ? 'primary' : ''">{{ page.title }}</button>

 1
Author: zalog,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-09-11 10:35:56

No pude encontrar una buena solución existente, así que construí mi propia directiva que hace esto.

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

@Directive({
  selector: '[dynamic-attr]'
})
export class DynamicAttrDirective {
  @Input('dynamic-attr') attr: string;
  private _el: ElementRef;

  constructor(el: ElementRef) {
    this._el = el;
  }

  ngOnInit() {
    if (this.attr === '') return null;
    const node = document.createAttribute(this.attr);
    this._el.nativeElement.setAttributeNode(node);
  }
}

Luego tu html:

<div dynamic-attr="{{hasMargin: 'margin-left' ? ''}}"></div>

 1
Author: Cappi10,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-02-19 14:10:38

Use NgClass

[ngClass]="{ 'mat-raised-button': trueCondition }"

Ejemplo de verdadera condición:

this.element === 'Today'

O una función booleana

getTruth()

Ejemplo completo:

  <button [ngClass]="{ 'mat-raised-button': trueCondition }">TEXT</button>

Si desea una clase predeterminada:

  <button [ngClass]="{ 'mat-raised-button': trueCondition, 'default-class': !trueCondition }">TEXT</button>
 0
Author: Moshe,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-06-16 20:04:05

Tengo otra idea sobre lo que podrías hacer.

Puede almacenar el html que desea reemplazar en una variable como una cadena y luego agregar / eliminar la directiva de ella como desee, utilizando el método bypassSecurityTrustHtml del DomSanitizer.

No resulta en una solución limpia, pero al menos no es necesario repetir el código.

 0
Author: LLL,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-06-20 17:06:33