詳細ガイド
テンプレート構文

テンプレート変数を理解する

テンプレート変数は、テンプレートの1つの部分から別の部分にデータを使用するのに役立ちます。 テンプレート変数を使用して、ユーザー入力に応答したり、アプリケーションのフォームを微調整したりなどのタスクを実行します。

テンプレート変数は、以下を参照できます。

構文

テンプレートでは、ハッシュ記号 # を使用してテンプレート変数を宣言します。 次のテンプレート変数 #phone は、<input> 要素を値とする phone 変数を宣言します。

src/app/app.component.html

      
<h1>Template reference variables</h1>
<div>
<h2>Pass value to an event handler</h2>
<p>See console for output.</p>
<input #phone placeholder="phone number" />
<!-- lots of other elements -->
<!-- phone refers to the input element; pass its `value` to an event handler -->
<button type="button" (click)="callPhone(phone.value)">Call</button>
</div>
<hr />
<div>
<h2>Template reference variable with disabled button</h2>
<p>btn refers to the button element.</p>
<button
type="button"
#btn
disabled
[innerHTML]="'disabled by attribute: ' + btn.disabled"
></button>
</div>
<hr />
<h2>Reference variables, forms, and NgForm</h2>
<form #itemForm="ngForm" (ngSubmit)="onSubmit(itemForm)">
<label for="name">Name</label>
<input type="text" id="name" class="form-control" name="name" ngModel required />
<button type="submit">Submit</button>
</form>
<div [hidden]="!itemForm.form.valid">
<p>{{ submitMessage }}</p>
</div>
<p>JSON: {{ itemForm.form.value | json }}</p>
<hr />
<h2>Template Reference Variable Scope</h2>
<p>This section demonstrates in which situations you can access local template reference variables (<code>#ref</code>).</p>
<h3>Accessing in a child template</h3>
<!-- Accessing a template reference variable from an inner template
works as the context is inherited. Try changing the text in the
input to see how it is immediately reflected through the template
reference variable. -->
<div class="example">
<input #ref1 type="text" [(ngModel)]="firstExample" />
@if (true) {
<span>Value: {{ ref1.value }}</span>
}
</div>
<!-- In this case there's a "hidden" ng-template around the
span and the definition of the variable is outside of it. Thus, you access a template variable from a parent template (which is logical as the context is inherited). -->
<p>Here's the desugared syntax:</p>
<pre><code [innerText]="desugared1"></code></pre>
<h3>Accessing from outside parent template. (Doesn't work.)</h3>
<!-- Accessing the template reference variable from outside the parent template does
not work. The value to the right is empty and changing the
value of the input will have no effect. -->
<div class="example">
@if (true) {
<input #ref2 type="text" [(ngModel)]="secondExample" />
}
<!-- <span>Value: {{ ref2?.value }}</span> -->
<!-- uncomment the above and the app breaks -->
</div>
<p>Here's the desugared syntax:</p>
<pre><code [innerText]="desugared2"></code></pre>
<h3>*ngFor and template reference variable scope</h3>
<!-- The template is instantiated twice because *ngFor iterates
over the two items in the array, so it's impossible to define what ref2 is referencing. -->
<pre><code [innerText]="ngForExample"></code></pre>
<h3>Accessing a on an <code>ng-template</code></h3>
See the console output to see that when you declare the variable on an <code>ng-template</code>, the variable refers to a <code>TemplateRef</code> instance, which represents the template.
<ng-template #ref3></ng-template>
<button type="button" (click)="log(ref3)">Log type of #ref</button>

コンポーネントのテンプレートのどこでもテンプレート変数を参照します。 ここでは、テンプレートの下にある <button>phone 変数を参照しています。

src/app/app.component.html

      
<h1>Template reference variables</h1>
<div>
<h2>Pass value to an event handler</h2>
<p>See console for output.</p>
<input #phone placeholder="phone number" />
<!-- lots of other elements -->
<!-- phone refers to the input element; pass its `value` to an event handler -->
<button type="button" (click)="callPhone(phone.value)">Call</button>
</div>
<hr />
<div>
<h2>Template reference variable with disabled button</h2>
<p>btn refers to the button element.</p>
<button
type="button"
#btn
disabled
[innerHTML]="'disabled by attribute: ' + btn.disabled"
></button>
</div>
<hr />
<h2>Reference variables, forms, and NgForm</h2>
<form #itemForm="ngForm" (ngSubmit)="onSubmit(itemForm)">
<label for="name">Name</label>
<input type="text" id="name" class="form-control" name="name" ngModel required />
<button type="submit">Submit</button>
</form>
<div [hidden]="!itemForm.form.valid">
<p>{{ submitMessage }}</p>
</div>
<p>JSON: {{ itemForm.form.value | json }}</p>
<hr />
<h2>Template Reference Variable Scope</h2>
<p>This section demonstrates in which situations you can access local template reference variables (<code>#ref</code>).</p>
<h3>Accessing in a child template</h3>
<!-- Accessing a template reference variable from an inner template
works as the context is inherited. Try changing the text in the
input to see how it is immediately reflected through the template
reference variable. -->
<div class="example">
<input #ref1 type="text" [(ngModel)]="firstExample" />
@if (true) {
<span>Value: {{ ref1.value }}</span>
}
</div>
<!-- In this case there's a "hidden" ng-template around the
span and the definition of the variable is outside of it. Thus, you access a template variable from a parent template (which is logical as the context is inherited). -->
<p>Here's the desugared syntax:</p>
<pre><code [innerText]="desugared1"></code></pre>
<h3>Accessing from outside parent template. (Doesn't work.)</h3>
<!-- Accessing the template reference variable from outside the parent template does
not work. The value to the right is empty and changing the
value of the input will have no effect. -->
<div class="example">
@if (true) {
<input #ref2 type="text" [(ngModel)]="secondExample" />
}
<!-- <span>Value: {{ ref2?.value }}</span> -->
<!-- uncomment the above and the app breaks -->
</div>
<p>Here's the desugared syntax:</p>
<pre><code [innerText]="desugared2"></code></pre>
<h3>*ngFor and template reference variable scope</h3>
<!-- The template is instantiated twice because *ngFor iterates
over the two items in the array, so it's impossible to define what ref2 is referencing. -->
<pre><code [innerText]="ngForExample"></code></pre>
<h3>Accessing a on an <code>ng-template</code></h3>
See the console output to see that when you declare the variable on an <code>ng-template</code>, the variable refers to a <code>TemplateRef</code> instance, which represents the template.
<ng-template #ref3></ng-template>
<button type="button" (click)="log(ref3)">Log type of #ref</button>

Angularがテンプレート変数に値を割り当てる方法

Angularは、テンプレート変数を宣言した場所に基づいて、テンプレート変数に値を割り当てます。

  • コンポーネントで変数を宣言した場合、変数はコンポーネントインスタンスを参照します。
  • 標準のHTMLタグで変数を宣言した場合、変数は要素を参照します。
  • <ng-template> 要素で変数を宣言した場合、変数はテンプレートを表す TemplateRef インスタンスを参照します。 <ng-template> の詳細については、構造ディレクティブAngularがアスタリスク * 構文を使用する方法を参照してください。

名前を指定する変数

変数が #var="ngModel" のように右側に名前を指定している場合、変数は exportAs 名が一致する要素の指令またはコンポーネントを参照します。

テンプレート変数と NgForm の使用

ほとんどの場合、Angularはテンプレート変数の値を、その変数が発生した要素に設定します。 前の例では、phone は電話番号 <input> を参照します。 ボタンのクリックハンドラーは、<input> の値をコンポーネントの callPhone() メソッドに渡します。

NgForm 指令は、指令の exportAs 名を参照することで、別の値への参照を取得する方法を示しています。 次の例では、テンプレート変数 itemForm は、HTMLで区切られた3回表示されます。

src/app/hero-form.component.html

      
<h1>Template reference variables</h1>
<div>
<h2>Pass value to an event handler</h2>
<p>See console for output.</p>
<input #phone placeholder="phone number" />
<!-- lots of other elements -->
<!-- phone refers to the input element; pass its `value` to an event handler -->
<button type="button" (click)="callPhone(phone.value)">Call</button>
</div>
<hr />
<div>
<h2>Template reference variable with disabled button</h2>
<p>btn refers to the button element.</p>
<button
type="button"
#btn
disabled
[innerHTML]="'disabled by attribute: ' + btn.disabled"
></button>
</div>
<hr />
<h2>Reference variables, forms, and NgForm</h2>
<form #itemForm="ngForm" (ngSubmit)="onSubmit(itemForm)">
<label for="name">Name</label>
<input type="text" id="name" class="form-control" name="name" ngModel required />
<button type="submit">Submit</button>
</form>
<div [hidden]="!itemForm.form.valid">
<p>{{ submitMessage }}</p>
</div>
<p>JSON: {{ itemForm.form.value | json }}</p>
<hr />
<h2>Template Reference Variable Scope</h2>
<p>This section demonstrates in which situations you can access local template reference variables (<code>#ref</code>).</p>
<h3>Accessing in a child template</h3>
<!-- Accessing a template reference variable from an inner template
works as the context is inherited. Try changing the text in the
input to see how it is immediately reflected through the template
reference variable. -->
<div class="example">
<input #ref1 type="text" [(ngModel)]="firstExample" />
@if (true) {
<span>Value: {{ ref1.value }}</span>
}
</div>
<!-- In this case there's a "hidden" ng-template around the
span and the definition of the variable is outside of it. Thus, you access a template variable from a parent template (which is logical as the context is inherited). -->
<p>Here's the desugared syntax:</p>
<pre><code [innerText]="desugared1"></code></pre>
<h3>Accessing from outside parent template. (Doesn't work.)</h3>
<!-- Accessing the template reference variable from outside the parent template does
not work. The value to the right is empty and changing the
value of the input will have no effect. -->
<div class="example">
@if (true) {
<input #ref2 type="text" [(ngModel)]="secondExample" />
}
<!-- <span>Value: {{ ref2?.value }}</span> -->
<!-- uncomment the above and the app breaks -->
</div>
<p>Here's the desugared syntax:</p>
<pre><code [innerText]="desugared2"></code></pre>
<h3>*ngFor and template reference variable scope</h3>
<!-- The template is instantiated twice because *ngFor iterates
over the two items in the array, so it's impossible to define what ref2 is referencing. -->
<pre><code [innerText]="ngForExample"></code></pre>
<h3>Accessing a on an <code>ng-template</code></h3>
See the console output to see that when you declare the variable on an <code>ng-template</code>, the variable refers to a <code>TemplateRef</code> instance, which represents the template.
<ng-template #ref3></ng-template>
<button type="button" (click)="log(ref3)">Log type of #ref</button>

ngForm 属性値がなければ、itemForm の参照値は HTMLFormElement<form> になります。 要素がAngularコンポーネントの場合、属性値のない参照は自動的にコンポーネントインスタンスを参照します。それ以外の場合は、属性値のない参照はDOM要素を参照します。これは、要素に1つ以上の指令が適用されていても同じです。

テンプレート変数のスコープ

JavaScriptまたはTypeScriptコードの変数と同様に、テンプレート変数は、その変数を宣言したテンプレートにスコープされています。

同様に、*ngIf*ngFor などの構造ディレクティブ、または <ng-template> 宣言はJavaScriptの iffor などの制御フロー文が新しい字句スコープを作成するのと同じように新しいネストされたテンプレートスコープを作成します。これらの構造ディレクティブのいずれか内にあるテンプレート変数には、境界の外からアクセスできません。

HELPFUL: テンプレート内で変数を1回だけ定義してください。これにより、実行時の値が予測可能になります。

ネストされたテンプレートへのアクセス

内部テンプレートは、外部テンプレートが定義したテンプレート変数にアクセスできます。

次の例では、<input> 内のテキストを変更すると、<span> 内の値も変更されます。これは、Angularがテンプレート変数 ref1 を通じて変更をすぐに更新するためです。

src/app/app.component.html

      
<h1>Template reference variables</h1>
<div>
<h2>Pass value to an event handler</h2>
<p>See console for output.</p>
<input #phone placeholder="phone number" />
<!-- lots of other elements -->
<!-- phone refers to the input element; pass its `value` to an event handler -->
<button type="button" (click)="callPhone(phone.value)">Call</button>
</div>
<hr />
<div>
<h2>Template reference variable with disabled button</h2>
<p>btn refers to the button element.</p>
<button
type="button"
#btn
disabled
[innerHTML]="'disabled by attribute: ' + btn.disabled"
></button>
</div>
<hr />
<h2>Reference variables, forms, and NgForm</h2>
<form #itemForm="ngForm" (ngSubmit)="onSubmit(itemForm)">
<label for="name">Name</label>
<input type="text" id="name" class="form-control" name="name" ngModel required />
<button type="submit">Submit</button>
</form>
<div [hidden]="!itemForm.form.valid">
<p>{{ submitMessage }}</p>
</div>
<p>JSON: {{ itemForm.form.value | json }}</p>
<hr />
<h2>Template Reference Variable Scope</h2>
<p>This section demonstrates in which situations you can access local template reference variables (<code>#ref</code>).</p>
<h3>Accessing in a child template</h3>
<!-- Accessing a template reference variable from an inner template
works as the context is inherited. Try changing the text in the
input to see how it is immediately reflected through the template
reference variable. -->
<div class="example">
<input #ref1 type="text" [(ngModel)]="firstExample" />
@if (true) {
<span>Value: {{ ref1.value }}</span>
}
</div>
<!-- In this case there's a "hidden" ng-template around the
span and the definition of the variable is outside of it. Thus, you access a template variable from a parent template (which is logical as the context is inherited). -->
<p>Here's the desugared syntax:</p>
<pre><code [innerText]="desugared1"></code></pre>
<h3>Accessing from outside parent template. (Doesn't work.)</h3>
<!-- Accessing the template reference variable from outside the parent template does
not work. The value to the right is empty and changing the
value of the input will have no effect. -->
<div class="example">
@if (true) {
<input #ref2 type="text" [(ngModel)]="secondExample" />
}
<!-- <span>Value: {{ ref2?.value }}</span> -->
<!-- uncomment the above and the app breaks -->
</div>
<p>Here's the desugared syntax:</p>
<pre><code [innerText]="desugared2"></code></pre>
<h3>*ngFor and template reference variable scope</h3>
<!-- The template is instantiated twice because *ngFor iterates
over the two items in the array, so it's impossible to define what ref2 is referencing. -->
<pre><code [innerText]="ngForExample"></code></pre>
<h3>Accessing a on an <code>ng-template</code></h3>
See the console output to see that when you declare the variable on an <code>ng-template</code>, the variable refers to a <code>TemplateRef</code> instance, which represents the template.
<ng-template #ref3></ng-template>
<button type="button" (click)="log(ref3)">Log type of #ref</button>

この場合、<span>*ngIf は新しいテンプレートスコープを作成し、そのスコープには親スコープの ref1 変数が含まれます。

ただし、親テンプレートから子スコープのテンプレート変数にはアクセスできません。

      
<input *ngIf="true" #ref2 type="text" [(ngModel)]="secondExample" />
<span>Value: {{ ref2?.value }}</span> <!-- 機能しません -->

ここでは、ref2*ngIf によって作成された子スコープで宣言されており、親テンプレートからはアクセスできません。

テンプレート入力変数

テンプレート入力変数 は、そのテンプレートのインスタンスが作成されるときに値が設定される変数です。構造ディレクティブの記述 を参照してください。

テンプレート入力変数は、NgFor の長形式の使用で確認できます。

      
<ul>
<ng-template ngFor let-hero [ngForOf]="heroes">
<li>{{hero.name}}
</ng-template>
</ul>

NgFor 指令は、heroes 配列内の各ヒーローに対してこの <ng-template> を1回インスタンス化し、各インスタンスに対して hero 変数を適切に設定します。

<ng-template> がインスタンス化されると、複数の名前付き値を渡すことができ、これらは異なるテンプレート入力変数にバインドできます。入力変数の let- 宣言の右側は、その変数にどの値を使用するかを指定できます。

たとえば、NgFor は配列内の各ヒーローの index にもアクセスできます。

      
<ul>
<ng-template ngFor let-hero let-i="index" [ngForOf]="heroes">
<li>Hero number {{i}}: {{hero.name}}
</ng-template>
</ul>

次へ