ngattr change attribute angular angular-material angular2-forms angular2-directives angular-material2

angular - change - Aplicar una directiva condicionalmente



ngattr angular 4 (12)

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

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

Por ejemplo:

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

Otro ejemplo: creé una forma reactiva dinámica básica en plunker. Estoy usando la directiva formArrayName 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 alguna solución.

Aquí está el enlace de plunker: https://plnkr.co/edit/oPZ7PyBSf8jjYa2KVh4J?p=preview

Realmente agradecería cualquier contribución.

¡Gracias por adelantado!


A partir del 18 de enero de 2019, así es como agregué una directiva condicionalmente en Angular 5 y superior. Necesitaba cambiar el color del componente <app-nav> basado en darkMode . Si la página estaba en modo oscuro o no.

Esto funcionó para mí:

<app-nav [color]="darkMode ? ''orange'':''green''"></app-nav>

Espero que esto ayude a alguien.

EDITAR

Esto cambia el valor de un atributo (color) en función de una condición. Simplemente sucede que el color se define usando una directiva. Entonces, cualquiera que lea esto, no se confunda, esto no es aplicar una directiva condicionalmente (es decir, lo que significa agregar o eliminar una directiva al dom en función de una condición)


Actualmente, 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 existe un problema creado para el mismo con angular2 , por lo que también debería ser el caso con angular4.

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

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


Como otros también han declarado, las directives no pueden aplicarse dinámicamente.

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

<!-- 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>

Haría el truco. Plunker


Como ya se señaló, esto no parece ser posible. Una cosa que puede usarse para evitar al menos cierta 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 material angular:

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

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


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 de aplicación de la variable de entrada:

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

En el método de la directiva, verifique la variable this.options.apply y aplique la lógica de la directiva en función de la condición:

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


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

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

Funciona para angular 4, iónico 3 como este:

[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>


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); } }

Entonces tu html:

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


No sé si puede aplicar directivas en función de una condición, pero una solución sería tener 2 botones y mostrarlos en función de una condición .

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

Editar: tal vez this sea ​​útil.


Puede usar el siguiente método:

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

Aplicado lo mismo a tu plunker: fork

Actualizar:

Como condition ? '''' : null condition ? '''' : null funciona como el valor:

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

Actualización: actualización de plunker: fork (problemas de versión corregidos, tenga en cuenta que la pregunta se basó originalmente en angular 4)


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''); } } }


Tengo otra idea sobre lo que puedes hacer.

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

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


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 quieres una clase predeterminada:

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