web-dev-qa-db-fra.com

Comment déclarer une variable dans un modèle dans Angular

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?

95
Scipion

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.
48
Günter Zöchbauer

Mettre à jour

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

Origine

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>
83
yurzui

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>
48
kayjtea

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.

8
Aaron

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>
6
Lemmy4555

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>
1
The Mechanic

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>
1
Jack Rus

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é:

  • changer le préfixe de 'ng' en 'app' (vous devez utiliser le préfixe personnalisé de votre application)
  • changer 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

0
Keego

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'};
}
0
Philip John

Réponse courte qui aide à quelqu'un

  • La variable de référence de modèle fait souvent référence à un élément DOM dans un modèle.
  • Faites également référence à angular ou au composant Web et à la directive.
  • Cela signifie que vous pouvez facilement accéder à la varible n'importe où dans un modèle

enter image description here

enter image description here

  • Déclarez la variable de référence à l'aide du symbole dièse (#)
  • Peut passer une variable en tant que paramètre sur un événement

enter image description here

  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.

enter image description here

https://stackblitz.com/edit/angular-2-template-reference-variable

0
Mano