Angularのテンプレートでは、バインディングによりテンプレートから作成されたUIの一部(DOM要素、ディレクティブ、またはコンポーネント)とモデル(テンプレートが属するコンポーネントインスタンス)間にライブ接続が確立されます。この接続はビューをモデルと同期させたり、ビューでイベントやユーザーアクションが発生したときにモデルに通知したり、その両方を行うために使用できます。Angularの 変更検知 アルゴリズムは、ビューとモデルを同期させる役割を担います。
バインディングの例には、次のようなものがあります。
- テキスト補間
- プロパティバインディング
- イベントバインディング
- 双方向バインディング
バインディングには常に、ターゲット(バインドされた値を受け取るもの)と、テンプレート式(モデルから値を生成するもの)の2つの部分があります。
構文
テンプレート式はJavaScript式に似ています。 多くのJavaScript式は有効なテンプレート式ですが、以下の例外があります。
副作用を持つ、または副作用を促進するJavaScript式は使用できません。具体的には、以下を含みます。
- 代入 (
=
,+=
,-=
,...
) new
,typeof
, またはinstanceof
などの演算子;
または,
を使用した式チェーン- インクリメントおよびデクリメント演算子
++
および--
- ES2015+ の演算子のいくつか
JavaScript構文からのその他の顕著な違いには、次のようなものがあります。
|
や&
などのビット単位の演算子はサポートされていません。
式のコンテキスト
補間された式には、式が属するアプリケーションの特定の部分であるコンテキストがあります。通常、このコンテキストはコンポーネントインスタンスです。
次のスニペットでは、recommended
式と itemImageUrl2
式は、AppComponent
のプロパティを参照しています。
src/app/app.component.html
<div> <h1>Interpolation and Template Expressions</h1> <hr /> <div> <h2>Interpolation</h2> <h3>Current customer: {{ currentCustomer }}</h3> <p>{{ title }}</p> <div><img alt="item" src="{{ itemImageUrl }}"></div> <h3>Evaluating template expressions </h3> <h4>Simple evaluation (to a string):</h4> <!-- "The sum of 1 + 1 is 2" --> <p>The sum of 1 + 1 is {{ 1 + 1 }}.</p> <h4>Evaluates using a method (also evaluates to a string):</h4> <!-- "The sum of 1 + 1 is not 4" --> <p>The sum of 1 + 1 is not {{ 1 + 1 + getVal() }}.</p> </div> <hr /><h2>Expression Context</h2><div> <h3>Component context, properties of app.component.ts:</h3> <h4>{{ recommended }}</h4> <img alt="item 2" [src]="itemImageUrl2"></div><div> <h4>Template context, template input variables (let customer):</h4> <ul> @for (customer of customers; track customer) { <li>{{ customer.name }}</li> } </ul></div><div (keyup)="0"> <h4>Template context: template reference variables (#customerInput):</h4> <label for="customer-input">Type something: <input id="customer-input" #customerInput>{{ customerInput.value }} </label></div></div>
式は、テンプレート入力変数 や テンプレート参照変数 などの、テンプレート のコンテキストのプロパティも参照できます。
次の例では、customer
のテンプレート入力変数を使用しています。
src/app/app.component.html (template input variable)
<div> <h1>Interpolation and Template Expressions</h1> <hr /> <div> <h2>Interpolation</h2> <h3>Current customer: {{ currentCustomer }}</h3> <p>{{ title }}</p> <div><img alt="item" src="{{ itemImageUrl }}"></div> <h3>Evaluating template expressions </h3> <h4>Simple evaluation (to a string):</h4> <!-- "The sum of 1 + 1 is 2" --> <p>The sum of 1 + 1 is {{ 1 + 1 }}.</p> <h4>Evaluates using a method (also evaluates to a string):</h4> <!-- "The sum of 1 + 1 is not 4" --> <p>The sum of 1 + 1 is not {{ 1 + 1 + getVal() }}.</p> </div> <hr /><h2>Expression Context</h2><div> <h3>Component context, properties of app.component.ts:</h3> <h4>{{ recommended }}</h4> <img alt="item 2" [src]="itemImageUrl2"></div><div> <h4>Template context, template input variables (let customer):</h4> <ul> @for (customer of customers; track customer) { <li>{{ customer.name }}</li> } </ul></div><div (keyup)="0"> <h4>Template context: template reference variables (#customerInput):</h4> <label for="customer-input">Type something: <input id="customer-input" #customerInput>{{ customerInput.value }} </label></div></div>
次の例では、#customerInput
のテンプレート参照変数を使用しています。
src/app/app.component.html (template reference variable)
<div> <h1>Interpolation and Template Expressions</h1> <hr /> <div> <h2>Interpolation</h2> <h3>Current customer: {{ currentCustomer }}</h3> <p>{{ title }}</p> <div><img alt="item" src="{{ itemImageUrl }}"></div> <h3>Evaluating template expressions </h3> <h4>Simple evaluation (to a string):</h4> <!-- "The sum of 1 + 1 is 2" --> <p>The sum of 1 + 1 is {{ 1 + 1 }}.</p> <h4>Evaluates using a method (also evaluates to a string):</h4> <!-- "The sum of 1 + 1 is not 4" --> <p>The sum of 1 + 1 is not {{ 1 + 1 + getVal() }}.</p> </div> <hr /><h2>Expression Context</h2><div> <h3>Component context, properties of app.component.ts:</h3> <h4>{{ recommended }}</h4> <img alt="item 2" [src]="itemImageUrl2"></div><div> <h4>Template context, template input variables (let customer):</h4> <ul> @for (customer of customers; track customer) { <li>{{ customer.name }}</li> } </ul></div><div (keyup)="0"> <h4>Template context: template reference variables (#customerInput):</h4> <label for="customer-input">Type something: <input id="customer-input" #customerInput>{{ customerInput.value }} </label></div></div>
HELPFUL: テンプレート式は、undefined
を除いて、グローバル名前空間内のものは何も参照できません。 window
や document
は参照できません。また、console.log()
や Math.max()
を呼び出すことができず、式のコンテキストのメンバーの参照に限定されています。
名前衝突の防止
式が評価されるコンテキストは、テンプレート変数、ディレクティブのコンテキストオブジェクト(存在する場合)、およびコンポーネントのメンバーの結合です。 複数の名前空間に属する名前を参照する場合、Angularは次の優先順位ロジックを適用してコンテキストを決定します。
- テンプレート変数名
- ディレクティブのコンテキスト内の名前
- コンポーネントのメンバー名
変数が別のコンテキストの変数を隠すことを防ぐために、変数名を一意に保ちます。
次の例では、AppComponent
テンプレートは、customer
のPadmaに挨拶します。
@for
は、customers
配列内の各 customer
をリスト表示します。
src/app/app.component.ts
import {Component} from '@angular/core';import {NgFor} from '@angular/common';@Component({ standalone: true, template: ` <div> <!-- Hello, Padma --> <h1>Hello, {{customer}}</h1> <ul> <!-- Ebony and Chiho in a list--> @for (customer of customers; track customer) { <li>{{ customer.value }}</li> } </ul> </div> `,})export class AppComponent { customers = [{value: 'Ebony'}, {value: 'Chiho'}]; customer = 'Padma';}
@for
内の customer
は、@for によって定義された暗黙の <ng-template>
のコンテキストにあります。これは、customers
配列内の各 customer
を参照し、"Ebony" と "Chiho" を表示します。"Padma" は、その配列内に存在しないため表示されません。
一方、<h1>
は、コンポーネントクラスの customer
プロパティの値にバインドされた "Padma" を表示します。
式のベストプラクティス
テンプレート式を使用する際には、次のベストプラクティスに従ってください。
- 短い式を使用する
可能な限り、プロパティ名やメソッド呼び出しを使用します。アプリケーションロジックとビジネスロジックは、開発とテストが可能なコンポーネントに保持します。
- 迅速な実行
Angularは、変更検知サイクルのたびにテンプレート式を実行します。Promise解決、HTTP結果、タイマーイベント、キー押下、マウス移動など、多くの非同期アクティビティが変更検知サイクルをトリガーします。
特に低速なデバイスでは、ユーザー体験をできるだけ効率的にするために、式は迅速に終了する必要があります。計算に多くのリソースを必要とする場合は、値をキャッシュすることを検討してください。
可視的な副作用なし
Angularの単方向データフローモデルに従って、テンプレート式は、ターゲットプロパティの値以外、アプリケーションの状態を変更すべきではありません。コンポーネントの値を読み取ることは、他の表示される値を変更すべきではありません。ビューは、1回のレンダリングパス全体で安定している必要があります。
冪等 な式は副作用がなく、Angularの変更検知のパフォーマンスを向上させます。Angularの用語では、冪等な式は、依存する値のいずれかが変更されるまでは、常に まったく同じもの を返します。
依存する値は、イベントループの1回のターン中に変更されるべきではありません。べき等な式が文字列または数値を返す場合、それを連続して2回呼び出した場合、同じ文字列または数値を返します。式がオブジェクト(array
を含む)を返す場合、それを連続して2回呼び出した場合、同じオブジェクト 参照 を返します。