次のようなテンプレートがあります。
<div>
<span>{{aVariable}}</span>
</div>
そしてで終わることを望む:
<div "let a = aVariable">
<span>{{a}}</span>
</div>
する方法はありますか?
更新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>
(未検証)
#aVariable
はVarDirective
への参照を作成します(exportAs: 'var'
)var="abc"
はVarDirective
をインスタンス化し、文字列値"abc"
をその値入力に渡します。aVariable.var
は、var
ディレクティブvar
入力に割り当てられた値を読み取ります。コメントとして@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>
また見なさい
アンギュラ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>
醜い、しかし:
<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>
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"
これは私が書いたディレクティブで、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は任意の有効なローカル変数名にすることができます。
私はこれをお勧めします: https://medium.com/@AustinMatherne/angular-let-directive-a168d4248138
このディレクティブにより、次のように書くことができます。
<div *ngLet="'myVal' as myVar">
<span> {{ myVar }} </span>
</div>
それははるかに簡単です、何も追加の必要はありません。私の例では、変数「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>
私は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>
私はこれを行うためのディレクティブを作成するというアプローチが好きでした(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
}
}
主な変更点は以下のとおりです。
appLet: T
をappLet: T | null
に変更Angularチームが公式のngLetディレクティブを作成したのではなくwhatevsを作成した理由はよくわかりません。
元のソースコードのクレジットは@AustinMatherneにあります
関数の応答を取得してそれを変数に設定したい場合は、テンプレートの変更を避けるためにng-container
を使用して、テンプレート内で次のように使用できます。
<ng-container *ngIf="methodName(parameters) as respObject">
{{respObject.name}}
</ng-container>
そしてコンポーネントのメソッドは次のようになります。
methodName(parameters: any): any {
return {name: 'Test name'};
}
誰かに役立つ短い答え
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の場合、各テンプレートには独自の入力変数セットがあるため、少し異なります。
https://stackblitz.com/edit/angular-2-template-reference-variable