web-dev-qa-db-ja.com

テンプレートで変数を宣言する方法 Angular

次のようなテンプレートがあります。

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

そしてで終わることを望む:

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

する方法はありますか?

115
Scipion

更新3

問題2451はAngular 4.0.0で修正されました

また見なさい

更新2

これはサポートされていません。

テンプレート変数がありますが、任意の値を代入することはサポートされていません。それらは、それらが適用される要素、ディレクティブまたはコンポーネントのエクスポートされた名前、およびngForのような構造ディレクティブのスコープ変数を参照するためにのみ使用できます。

https://github.com/angular/angular/issues/2451も参照してください

更新1

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

そしてそれを初期化する

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

または

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

そしてのような変数を使う

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

(未検証)

  • #aVariableVarDirectiveへの参照を作成します(exportAs: 'var'
  • var="abc"VarDirectiveをインスタンス化し、文字列値"abc"をその値入力に渡します。
  • aVariable.varは、varディレクティブvar入力に割り当てられた値を読み取ります。
49

更新

コメントとして@Keithが述べたように

これはほとんどの場合うまくいくでしょうが、それは変数が真実であることに依存しているので一般的な解決策ではありません

それでOriginの答えは@Keithが言ったように働きます。もう1つアプローチがあります。 *ngIfのようなディレクティブを作成し、それを*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);
  }
}

この*ngVarディレクティブでは、次のものを使用できます。

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

または

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

または

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

または

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

プランカーの例Angular4 ngVar

また見なさい

原点

アンギュラ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

ビュー

<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)divのようなラッパーを作りたくない場合はng-containerを使用できます。

ビュー

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

醜い、しかし:

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

非同期パイプと共に使用する場合

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

Angular 2のtemplate要素、またはAngular 4+のng-templateを使用して、HTMLコードで変数を宣言できます。

テンプレートはコンテキストオブジェクトを持ち、そのプロパティはletバインディング構文を使って変数に割り当てることができます。テンプレートのアウトレットを指定する必要がありますが、それ自体への参照になることがあります。

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

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

カスタムプロパティの代わりにコンテキストオブジェクトの$implicitプロパティを使用すると、コード量を減らすことができます。

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

コンテキストオブジェクトは、リテラルオブジェクトまたは他の任意のバインディング式にすることができます。括弧で囲まれている場合でも、パイプでさえうまくいくようです。

ngTemplateOutletContextの有効な例:

  • [ngTemplateOutletContext]="{ aVariable: 123 }"
  • [ngTemplateOutletContext]="{ aVariable: (3.141592 | number:'3.1-5') }"
  • [ngTemplateOutletContext]="{ aVariable: anotherVariable }"let-a="aVariable"と共に使用
  • [ngTemplateOutletContext]="{ $implicit: anotherVariable }"let-aと共に使用
  • ctxがパブリックプロパティである[ngTemplateOutletContext]="ctx"
34
Steven Liekens

これは私が書いたディレクティブで、exportAsデコレータパラメータの使い方を拡張したもので、辞書をローカル変数として使うことができます。

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

テンプレートでは次のように使用できます。

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

もちろん#localは任意の有効なローカル変数名にすることができます。

8
Aaron

私はこれをお勧めします: https://medium.com/@AustinMatherne/angular-let-directive-a168d4248138

このディレクティブにより、次のように書くことができます。

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

それははるかに簡単です、何も追加の必要はありません。私の例では、変数「open」を宣言してから使用しています。

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

私はAngular 6xを使っていて、下のスニペットを使うことになった。私はタスクオブジェクトからユーザーを見つけるための場面です。それはユーザーの配列を含みますが、私は割り当てられたユーザーを選ぶべきです。

<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

私はこれを行うためのディレクティブを作成するというアプローチが好きでした(good call @yurzui)。

私はこの問題をうまく説明し、カスタムの letディレクティブ を提案するMediumの記事 Angular "let" Directive を見つけることになりました。最小限のコード変更で.

これが私が修正した要旨(投稿時)です。

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

主な変更点は以下のとおりです。

  • 接頭辞を 'ng'から 'app'に変更します(あなたのアプリのカスタム接頭辞はなんでも構いません)
  • appLet: TappLet: T | nullに変更

Angularチームが公式のngLetディレクティブを作成したのではなくwhatevsを作成した理由はよくわかりません。

元のソースコードのクレジットは@AustinMatherneにあります

0
Keego

関数の応答を取得してそれを変数に設定したい場合は、テンプレートの変更を避けるためにng-containerを使用して、テンプレート内で次のように使用できます。

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

そしてコンポーネントのメソッドは次のようになります。

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

誰かに役立つ短い答え

  • テンプレート参照変数は、多くの場合、テンプレート内のDOM要素を参照します。
  • angularまたはWebコンポーネントとディレクティブも参照します。
  • つまり、テンプレート内のどこからでも変数に簡単にアクセスできます。

enter image description here

enter image description here

  • ハッシュ記号(#)を使用して参照変数を宣言する
  • イベントのパラメーターとして変数を渡すことができます

enter image description here

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

*ただし、ViewChildデコレータを使用して、コンポーネント内で参照できます。

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

コンポーネント内のfirstNameInput変数を参照する

@ViewChild('firstNameInput') nameInputRef: ElementRef;

その後、コンポーネント内のどこでもthis.nameInputRefを使用できます。

ng-templateの使用

Ng-templateの場合、各テンプレートには独自の入力変数セットがあるため、少し異なります。

enter image description here

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

0
Mano