J'ai le modèle suivant:
<div>
<span>{{aVariable}}</span>
</div>
et voudrait se retrouver avec:
<div "let a = aVariable">
<span>{{a}}</span>
</div>
Y a-t-il un moyen de faire?
mise à jour 3
Le problème 2451 est corrigé dans Angular 4.0.0
Voir également
mise à jour 2
Ce n'est pas pris en charge.
Il existe des variables de modèle, mais l'attribution de valeurs arbitraires n'est pas prise en charge. Ils ne peuvent être utilisés que pour faire référence aux éléments auxquels ils sont appliqués, aux noms exportés de directives ou de composants et aux variables de portée pour les directives structurelles telles que ngFor
,
Voir aussi https://github.com/angular/angular/issues/2451
Mise à jour 1
@Directive({
selector: '[var]',
exportAs: 'var'
})
class VarDirective {
@Input() var:any;
}
et l'initialiser comme
<div #aVariable="var" var="abc"></div>
ou
<div #aVariable="var" [var]="'abc'"></div>
et utiliser la variable comme
<div>{{aVariable.var}}</div>
(pas testé)
#aVariable
crée une référence à la VarDirective
(exportAs: 'var'
)var="abc"
instancie la VarDirective
et passe la chaîne "abc"
à sa valeur entrée.aVariable.var
lit la valeur affectée à l'entrée var
directives var
.Comme @Keith mentionné dans les commentaires
cela fonctionnera dans la plupart des cas, mais ce n’est pas une solution générale, car cela repose sur la variable étant la vérité
Donc, la réponse de l'origine fonctionne comme @ Keith dit. Voici une autre approche. Nous pouvons simplement créer une directive comme *ngIf
et l'appeler *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);
}
}
avec cette directive *ngVar
, nous pouvons utiliser ce qui suit
<div *ngVar="false as variable">
<span>{{variable | json}}</span>
</div>
ou
<div *ngVar="false; let variable">
<span>{{variable | json}}</span>
</div>
ou
<div *ngVar="45 as variable">
<span>{{variable | json}}</span>
</div>
ou
<div *ngVar="{ x: 4 } as variable">
<span>{{variable | json}}</span>
</div>
Exemple de plunker Angular4 ngVar
Voir également
Angulaire v4
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
vue
<div *ngIf="{ a: 1, b: 2, c: 3 + x } as variable">
<span>{{variable.a}}</span>
<span>{{variable.b}}</span>
<span>{{variable.c}}</span>
</div>
composant.ts
export class AppComponent {
x = 5;
}
3) Si vous ne voulez pas créer de wrapper comme div
, vous pouvez utiliser ng-container
vue
<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>
Moche, mais:
<div *ngFor="let a of [aVariable]">
<span>{{a}}</span>
</div>
Lorsqu'il est utilisé avec un tuyau asynchrone:
<div *ngFor="let a of [aVariable | async]">
<span>{{a.prop1}}</span>
<span>{{a.prop2}}</span>
</div>
Voici une directive que j'ai écrite qui développe l'utilisation du paramètre décorAs exportAs et vous permet d'utiliser un dictionnaire en tant que variable locale.
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( ) {
}
}
Vous pouvez l'utiliser comme suit dans un modèle:
<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>
Bien sûr, #local peut être n’importe quel nom de variable locale valide.
Je suggérerais ceci: https://medium.com/@AustinMatherne/angular-let-directive-a168d4248138
Cette directive vous permet d’écrire quelque chose comme:
<div *ngLet="'myVal' as myVar">
<span> {{ myVar }} </span>
</div>
J'utilise 6x angulaire et j'ai fini par utiliser l'extrait ci-dessous . J'ai un scénario où je dois trouver l'utilisateur depuis un objet de tâche il contient un tableau d'utilisateurs mais je dois choisir un utilisateur assigné.
<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>
C'est beaucoup plus simple, pas besoin de rien de plus. Dans mon exemple, je déclare la variable "open", puis je l’utilise.
<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>
J'ai aimé l'approche consistant à créer une directive pour ce faire (bon appel @yurzui).
J'ai finalement trouvé un article Medium Directive angulaire "let" qui explique bien ce problème et propose une directive custom let qui s'est avérée très efficace pour mon cas d'utilisation avec des modifications minimales du code.
Voici le résumé (au moment de la publication) avec mes modifications:
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
}
}
Mes principaux changements ont été:
appLet: T
en appLet: T | null
Vous ne savez pas pourquoi l'équipe angulaire ne s'est pas contentée de faire une directive officielle de ngLet, mais quoi.
Le crédit de code source original va à @AustinMatherne
Si vous souhaitez obtenir la réponse d’une fonction et la définir comme variable, vous pouvez l’utiliser comme suit dans le modèle, en utilisant ng-container
pour éviter de modifier le modèle.
<ng-container *ngIf="methodName(parameters) as respObject">
{{respObject.name}}
</ng-container>
Et la méthode dans le composant peut être quelque chose comme
methodName(parameters: any): any {
return {name: 'Test name'};
}
Réponse courte qui aide à quelqu'un
show(lastName: HTMLInputElement){
this.fullName = this.nameInputRef.nativeElement.value + ' ' + lastName.value;
this.ctx.fullName = this.fullName;
}
* Cependant, vous pouvez utiliser le décorateur ViewChild pour le référencer dans votre composant.
import {ViewChild, ElementRef} from '@angular/core';
Référence firstNameInput variable à l'intérieur du composant
@ViewChild('firstNameInput') nameInputRef: ElementRef;
Après cela, vous pouvez utiliser this.nameInputRef n'importe où dans votre composant.
Travailler avec ng-template
Dans le cas de ng-template, c'est un peu différent parce que chaque modèle a son propre ensemble de variables d'entrée.
https://stackblitz.com/edit/angular-2-template-reference-variable