webentwicklung-frage-antwort-db.com.de

So deklarieren Sie eine Variable in einer Vorlage in Angular

Ich habe folgende Vorlage:

<div>
  <span>{{aVariable}}</span>
</div>

und möchte mit: 

<div "let a = aVariable">
  <span>{{a}}</span>
</div>

Gibt es einen Weg zu tun?

95
Scipion

Update 3

Das Problem 2451 wurde in Angular 4.0.0 behoben

Siehe auch

Update 2

Dies wird nicht unterstützt.

Es gibt Vorlagenvariablen, aber es wird nicht unterstützt, beliebige Werte zuzuweisen. Sie können nur verwendet werden, um auf die Elemente zu verweisen, auf die sie angewendet werden, um Namen von Direktiven oder Komponenten und Bereichsvariablen für strukturelle Direktiven wie ngFor zu exportieren.

Siehe auch https://github.com/angular/angular/issues/2451

Update 1

@Directive({
  selector: '[var]',
  exportAs: 'var'
})
class VarDirective {
  @Input() var:any;
}

und initialisiere es wie

<div #aVariable="var" var="abc"></div>

oder

<div #aVariable="var" [var]="'abc'"></div>

und benutze die Variable like

<div>{{aVariable.var}}</div>

(nicht getestet)

  • #aVariable erstellt einen Verweis auf die VarDirective (exportAs: 'var')
  • var="abc" instanziiert den VarDirective und übergibt den Zeichenkettenwert "abc" zu seiner Werteingabe.
  • aVariable.var liest den Wert, der der Eingabe var directives var zugewiesen wurde.
52

Aktualisieren

Als @Keith in Kommentaren erwähnt 

dies wird in den meisten Fällen funktionieren, aber es ist keine allgemeine Lösung, da es verlässt sich darauf, dass Variable wahr ist

Die Antwort von Origin funktioniert also, wie @Keith sagte. Hier ist ein weiterer Ansatz. Wir können einfach eine Direktive wie *ngIf erstellen und sie *ngVar nennen.

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

mit dieser *ngVar-Direktive können wir Folgendes verwenden

<div *ngVar="false as variable">
      <span>{{variable | json}}</span>
</div>

oder 

<div *ngVar="false; let variable">
    <span>{{variable | json}}</span>
</div>

oder

<div *ngVar="45 as variable">
    <span>{{variable | json}}</span>
</div>

oder 

<div *ngVar="{ x: 4 } as variable">
    <span>{{variable | json}}</span>
</div>

Plunker-Beispiel Angular4 ngVar

Siehe auch

Ursprung

Winkel 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

Aussicht

<div *ngIf="{ a: 1, b: 2, c: 3 + x } as variable">
  <span>{{variable.a}}</span>
  <span>{{variable.b}}</span>
  <span>{{variable.c}}</span>
</div>

component.ts

export class AppComponent {
  x = 5;
}

3) Wenn Sie keinen Wrapper wie div erstellen möchten, können Sie ng-container verwenden.

Aussicht

<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

Hässlich, aber:

<div *ngFor="let a of [aVariable]">
  <span>{{a}}</span>
</div>

Bei Verwendung mit asynchronem Rohr:

<div *ngFor="let a of [aVariable | async]">
  <span>{{a.prop1}}</span>
  <span>{{a.prop2}}</span>
</div>
48
kayjtea

Sie können Variablen in HTML-Code deklarieren, indem Sie ein template -Element in Angular 2 oder ng-template In Angular 4+) verwenden.

Vorlagen haben ein Kontextobjekt, dessen Eigenschaften Variablen mit der Bindungssyntax let zugewiesen werden können. Beachten Sie, dass Sie einen Ausgang für die Vorlage angeben müssen, dieser kann jedoch ein Verweis auf sich selbst sein.

<ng-template let-a="aVariable" [ngTemplateOutletContext]="{ aVariable: 123 }" [ngTemplateOutlet]="selfie" #selfie>
  <div>
    <span>{{a}}</span>
  </div>
</ng-template>

<!-- Output
<div>
  <span>123</span>
</div>
-->

Sie können die Codemenge verringern, indem Sie die Eigenschaft $implicit Des Kontextobjekts anstelle einer benutzerdefinierten Eigenschaft verwenden.

<ng-template let-a [ngTemplateOutletContext]="{ $implicit: 123 }" [ngTemplateOutlet]="t" #t>
  <div>
    <span>{{a}}</span>
  </div>
</ng-template>

Das Kontextobjekt kann ein Literalobjekt oder ein beliebiger anderer Bindungsausdruck sein. Sogar Pfeifen scheinen zu funktionieren, wenn sie von Klammern umgeben sind.

Gültige Beispiele für ngTemplateOutletContext:

  • [ngTemplateOutletContext]="{ aVariable: 123 }"
  • [ngTemplateOutletContext]="{ aVariable: (3.141592 | number:'3.1-5') }"
  • [ngTemplateOutletContext]="{ aVariable: anotherVariable }" Verwenden mit let-a="aVariable"
  • [ngTemplateOutletContext]="{ $implicit: anotherVariable }" Verwenden mit let-a
  • [ngTemplateOutletContext]="ctx" Wobei ctx eine öffentliche Eigenschaft ist
47
Steven Liekens

Hier ist eine Direktive, die ich geschrieben habe und die die Verwendung des Dekorators exportAs ausführt, und die Verwendung eines Wörterbuchs als lokale Variable ermöglicht.

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( ) {
    }
}

Sie können es in einer Vorlage wie folgt verwenden:

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

Natürlich kann #local jeder gültige lokale Variablenname sein.

8
Aaron

Ich würde folgendes vorschlagen: https://medium.com/@AustinMatherne/angular-let-directive-a168d4248138

Diese Direktive erlaubt es Ihnen, etwas zu schreiben:

<div *ngLet="'myVal' as myVar">
  <span> {{ myVar }} </span>
</div>
6
Lemmy4555

Ich verwende winkelförmiges 6x und habe am Ende das folgende Snippet verwendet: Ich habe ein Szenario, in dem ich Benutzer aus einem Aufgabenobjekt finden muss. Es enthält ein Array von Benutzern, aber ich muss den zugewiesenen Benutzer auswählen.

<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

Es ist viel einfacher, kein zusätzlicher Bedarf. In meinem Beispiel deklariere ich die Variable "open" und verwende sie dann. 

   <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

Der Ansatz, eine Direktive zu erstellen, hat mir gefallen (good call @yurzui). 

Am Ende fand ich einen mittleren Artikel Angular "let" Direktive , der dieses Problem gut erklärt und eine Custom let-Direktive vorschlägt , die für meinen Anwendungsfall mit minimalen Codeänderungen hervorragend funktionierte.

Hier ist der Gist (zum Zeitpunkt der Veröffentlichung) mit meinen Änderungen:

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

Meine wichtigsten Änderungen waren:

  • Ändern des Präfixes von "ng" in "app" (Sie sollten das benutzerdefinierte Präfix Ihrer App verwenden)
  • appLet: T in appLet: T | null ändern

Ich bin nicht sicher, warum das Angular-Team nicht nur eine offizielle ngLet-Direktive erstellt hat, sondern auch welche.

Der ursprüngliche Quellcodeguthaben geht an @AustinMatherne

0
Keego

Wenn Sie die Antwort einer Funktion abrufen und in eine Variable setzen möchten, können Sie sie wie folgt in der Vorlage verwenden. Verwenden Sie ng-container, um das Ändern der Vorlage zu vermeiden.

<ng-container *ngIf="methodName(parameters) as respObject">
  {{respObject.name}}
</ng-container>

Und die Methode in der Komponente kann so ähnlich sein

methodName(parameters: any): any {
  return {name: 'Test name'};
}
0
Philip John

Kurze Antwort die jemandem hilft

  • Vorlagenreferenzvariable verweist häufig auf ein DOM-Element in einer Vorlage.
  • Verweisen Sie auch auf angular oder Webkomponente und Direktive.
  • Das bedeutet, dass Sie überall in einer Vorlage problemlos auf die Variable zugreifen können

enter image description here

enter image description here

  • Referenzvariable mit dem Hash-Symbol (#) deklarieren
  • Kann eine Variable als Parameter für ein Ereignis übergeben

enter image description here

  show(lastName: HTMLInputElement){
    this.fullName = this.nameInputRef.nativeElement.value + ' ' + lastName.value;
    this.ctx.fullName = this.fullName;
  }

* Sie können jedoch ViewChild Decorator verwenden, um innerhalb Ihrer Komponente darauf zu verweisen.

import {ViewChild, ElementRef} from '@angular/core';

Referenz firstNameInput-Variable in Component

@ViewChild('firstNameInput') nameInputRef: ElementRef;

Danach können Sie this.nameInputRef an einer beliebigen Stelle in Ihrer Komponente verwenden.

Mit ng-template arbeiten

Im Fall von ng-template ist das etwas anders, da jedes Template einen eigenen Satz von Eingabevariablen hat.

enter image description here

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

0
Mano