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>