html - template - Cómo declarar una variable en una plantilla en angular
variables angular 4 (11)
Actualizar
Como @Keith mencionó en los comentarios
esto funcionará en la mayoría de los casos, pero no es una solución general ya que depende de que la variable sea verdadera
Entonces la respuesta de origen funciona como @Keith dijo.
Aquí hay un enfoque más.
Podemos crear directivas como
*ngIf
y llamarlo
*ngVar
ng-var.directive.ts
@Directive({
selector: ''[ngVar]'',
})
export class VarDirective {
@Input()
set ngVar(context: any) {
this.context.$implicit = this.context.ngVar = context;
this.updateView();
}
context: any = {};
constructor(private vcRef: ViewContainerRef, private templateRef: TemplateRef<any>) {}
updateView() {
this.vcRef.clear();
this.vcRef.createEmbeddedView(this.templateRef, this.context);
}
}
con esta directiva
*ngVar
podemos usar lo siguiente
<div *ngVar="false as variable">
<span>{{variable | json}}</span>
</div>
o
<div *ngVar="false; let variable">
<span>{{variable | json}}</span>
</div>
o
<div *ngVar="45 as variable">
<span>{{variable | json}}</span>
</div>
o
<div *ngVar="{ x: 4 } as variable">
<span>{{variable | json}}</span>
</div>
Ejemplo de Plunker Angular4 ngVar
Ver también
Origen
V4 angular
1)
div
+
ngIf
+
let
<div *ngIf="{ a: 1, b: 2 }; let variable">
<span>{{variable.a}}</span>
<span>{{variable.b}}</span>
</div>
2)
div
+
ngIf
+
as
ver
<div *ngIf="{ a: 1, b: 2, c: 3 + x } as variable">
<span>{{variable.a}}</span>
<span>{{variable.b}}</span>
<span>{{variable.c}}</span>
</div>
componente.ts
export class AppComponent {
x = 5;
}
3) Si no desea crear un contenedor como
div
, puede usar
ng-container
ver
<ng-container *ngIf="{ a: 1, b: 2, c: 3 + x } as variable">
<span>{{variable.a}}</span>
<span>{{variable.b}}</span>
<span>{{variable.c}}</span>
</ng-container>
Tengo la siguiente plantilla:
<div>
<span>{{aVariable}}</span>
</div>
y me gustaría terminar con:
<div "let a = aVariable">
<span>{{a}}</span>
</div>
¿Hay alguna manera de hacerlo?
Aquí hay una directiva que escribí que amplía el uso del parámetro decorador exportAs y le permite usar un diccionario como una variable local.
import { Directive, Input } from "@angular/core";
@Directive({
selector:"[localVariables]",
exportAs:"localVariables"
})
export class LocalVariables {
@Input("localVariables") set localVariables( struct: any ) {
if ( typeof struct === "object" ) {
for( var variableName in struct ) {
this[variableName] = struct[variableName];
}
}
}
constructor( ) {
}
}
Puede usarlo de la siguiente manera en una plantilla:
<div #local="localVariables" [localVariables]="{a: 1, b: 2, c: 3+2}">
<span>a = {{local.a}}</span>
<span>b = {{local.b}}</span>
<span>c = {{local.c}}</span>
</div>
Por supuesto, #local puede ser cualquier nombre de variable local válido.
En caso de que desee obtener la respuesta de una función y establecerla en una variable, puede usarla de la siguiente manera en la plantilla, usando
ng-container
para evitar modificar la plantilla.
<ng-container *ngIf="methodName(parameters) as respObject">
{{respObject.name}}
</ng-container>
Y el método en el componente puede ser algo como
methodName(parameters: any): any {
return {name: ''Test name''};
}
Es mucho más simple, no necesita nada adicional. En mi ejemplo, declaro la variable "abrir" y luego la uso.
<mat-accordion class="accord-align" #open>
<mat-expansion-panel hideToggle="true" (opened)="open.value=true" (closed)="open.value=false">
<mat-expansion-panel-header>
<span class="accord-title">Review Policy Summary</span>
<span class="spacer"></span>
<a *ngIf="!open.value" class="f-accent">SHOW</a>
<a *ngIf="open.value" class="f-accent">HIDE</a>
</mat-expansion-panel-header>
<mat-divider></mat-divider>
<!-- Quote Details Component -->
<quote-details [quote]="quote"></quote-details>
</mat-expansion-panel>
</mat-accordion>
Estoy usando angular 6x y terminé usando el fragmento a continuación. Tengo un escenario donde tengo que encontrar usuarios de un objeto de tarea. Contiene una variedad de usuarios, pero tengo que elegir el usuario asignado.
<ng-container *ngTemplateOutlet="memberTemplate; context:{o: getAssignee(task) }"></ng-container>
<ng-template #memberTemplate let-user="o">
<ng-container *ngIf="user">
<div class="d-flex flex-row-reverse">
<span class="image-block">
<ngx-avatar placement="left" ngbTooltip="{{user.firstName}} {{user.lastName}}" class="task-assigned" value="28%" [src]="user.googleId" size="32"></ngx-avatar>
</span>
</div>
</ng-container>
</ng-template>
Feo, pero:
<div *ngFor="let a of [aVariable]">
<span>{{a}}</span>
</div>
Cuando se usa con tubería asíncrona:
<div *ngFor="let a of [aVariable | async]">
<span>{{a.prop1}}</span>
<span>{{a.prop2}}</span>
</div>
Me gustó el enfoque de crear una directiva para hacer esto (buena llamada @yurzui).
Terminé encontrando un artículo medio de la https://medium.com/@AustinMatherne/angular-let-directive-a168d4248138 que explica muy bien este problema y propone una directiva let personalizada que terminó funcionando muy bien para mi caso de uso con cambios mínimos de código.
Aquí está la esencia (en el momento de la publicación) con mis modificaciones:
import { Directive, Input, TemplateRef, ViewContainerRef } from ''@angular/core''
interface LetContext <T> {
appLet: T | null
}
@Directive({
selector: ''[appLet]'',
})
export class LetDirective <T> {
private _context: LetContext <T> = { appLet: null }
constructor(_viewContainer: ViewContainerRef, _templateRef: TemplateRef <LetContext <T> >) {
_viewContainer.createEmbeddedView(_templateRef, this._context)
}
@Input()
set appLet(value: T) {
this._context.appLet = value
}
}
Mis principales cambios fueron:
- cambiar el prefijo de ''ng'' a ''aplicación'' (debe usar el prefijo personalizado de su aplicación)
-
cambiando
appLet: T
aappLet: T | null
appLet: T | null
No estoy seguro de por qué el equipo de Angular no acaba de hacer una directiva ngLet oficial, sino todo lo demás.
El crédito del código fuente original va a @AustinMatherne
Puede declarar variables en código html utilizando un elemento de
template
en Angular 2 o
ng-template
en Angular 4+.
Las plantillas tienen un objeto de contexto cuyas propiedades se pueden asignar a las variables utilizando la sintaxis de enlace
let
.
Tenga en cuenta que debe especificar una salida para la plantilla, pero puede ser una referencia a sí misma.
<ng-template let-a="aVariable" [ngTemplateOutletContext]="{ aVariable: 123 }" [ngTemplateOutlet]="selfie" #selfie>
<div>
<span>{{a}}</span>
</div>
</ng-template>
<!-- Output
<div>
<span>123</span>
</div>
-->
Puede reducir la cantidad de código utilizando la propiedad
$implicit
del objeto de contexto en lugar de una propiedad personalizada.
<ng-template let-a [ngTemplateOutletContext]="{ $implicit: 123 }" [ngTemplateOutlet]="t" #t>
<div>
<span>{{a}}</span>
</div>
</ng-template>
El objeto de contexto puede ser un objeto literal o cualquier otra expresión vinculante. Incluso las tuberías parecen funcionar cuando están rodeadas de paréntesis.
Ejemplos válidos de
ngTemplateOutletContext
:
-
[ngTemplateOutletContext]="{ aVariable: 123 }"
-
[ngTemplateOutletContext]="{ aVariable: (3.141592 | number:''3.1-5'') }"
-
[ngTemplateOutletContext]="{ aVariable: anotherVariable }"
usar conlet-a="aVariable"
-
[ngTemplateOutletContext]="{ $implicit: anotherVariable }"
usar conlet-a
-
[ngTemplateOutletContext]="ctx"
dondectx
es una propiedad pública
Sugeriría esto: https://medium.com/@AustinMatherne/angular-let-directive-a168d4248138
Esta directiva le permite escribir algo como:
<div *ngLet="''myVal'' as myVar">
<span> {{ myVar }} </span>
</div>
Respuesta corta que ayuda a alguien
- La variable de referencia de plantilla a menudo hace referencia al elemento DOM dentro de una plantilla.
- También referencia a componentes y directivas angulares o web.
- Eso significa que puede acceder fácilmente a la variable en cualquier lugar de una plantilla
- Declarar la variable de referencia usando el símbolo hash (#)
- Puede pasar una variable como parámetro en un evento
show(lastName: HTMLInputElement){
this.fullName = this.nameInputRef.nativeElement.value + '' '' + lastName.value;
this.ctx.fullName = this.fullName;
}
* Sin embargo, puede usar el decorador ViewChild para referenciarlo dentro de su componente.
import {ViewChild, ElementRef} from ''@angular/core'';
Referencia firstNameInput variable dentro de Component
@ViewChild(''firstNameInput'') nameInputRef: ElementRef;
Después de eso, puede usar this.nameInputRef en cualquier lugar dentro de su Componente.
Trabajando con ng-template
En el caso de ng-template, es un poco diferente porque cada plantilla tiene su propio conjunto de variables de entrada.
https://stackblitz.com/edit/angular-2-template-reference-variable
actualización 3
El problema 2451 se corrigió en Angular 4.0.0
Ver también
- https://github.com/angular/angular/pull/13297
- https://github.com/angular/angular/commit/b4db73d
- https://github.com/angular/angular/issues/13061
actualización 2
Esto no es compatible.
Hay variables de plantilla pero no es compatible para asignar valores arbitrarios.
Solo se pueden usar para referirse a los elementos a los que se aplican, los nombres exportados de directivas o componentes y las variables de alcance para directivas estructurales como
ngFor
,
Ver también https://github.com/angular/angular/issues/2451
Actualización 1
@Directive({
selector: ''[var]'',
exportAs: ''var''
})
class VarDirective {
@Input() var:any;
}
e inicializarlo como
<div #aVariable="var" var="abc"></div>
o
<div #aVariable="var" [var]="''abc''"></div>
y usar la variable como
<div>{{aVariable.var}}</div>
(no probado)
-
#aVariable
crea una referencia aVarDirective
(exportAs: ''var''
) -
var="abc"
VarDirective
instancia deVarDirective
y pasa el valor de cadena"abc"
a su entrada de valor. -
aVariable.var
lee el valor asignado a las directivasvar
inputvar
.