詳細ガイド
テンプレート

双方向バインディング

双方向バインディングは、要素に値をバインドすると同時に、その要素が変更をバインディングを通じて伝播できるようにする、簡潔な方法です。

構文

双方向バインディングの構文は、角括弧[]と丸括弧()を組み合わせた[()]です。これはプロパティバインディングの構文[]とイベントバインディングの構文()を組み合わせたものです。Angularコミュニティでは、この構文を非公式に「バナナインボックス」と呼んでいます。

フォームコントロールでの双方向バインディング

開発者は、ユーザーがコントロールを操作したときに、コンポーネントデータとフォームコントロールを同期させるため、双方向バインディングを頻繁に使用します。例えば、ユーザーがテキスト入力に入力すると、コンポーネントの状態が更新されます。

次の例では、ページのfirstName属性が動的に更新されます。

import {Component} from '@angular/core';import {FormsModule} from '@angular/forms';@Component({  imports: [FormsModule],  template: `    <main>      <h2>Hello {{ firstName }}!</h2>      <input type="text" [(ngModel)]="firstName" />    </main>  `,})export class App {  firstName = 'Ada';}

ネイティブフォームコントロールで双方向バインディングを使用するには、次の手順を実行する必要があります。

  1. @angular/formsからFormsModuleをインポートする
  2. 双方向バインディング構文(例:[(ngModel)])でngModelディレクティブを使用する
  3. 更新する状態(例:firstName)を割り当てる

これらが設定されると、Angularはテキスト入力の更新がコンポーネントの状態に正しく反映されるようにします。

NgModelの詳細については、公式ドキュメントを参照してください。

コンポーネント間の双方向バインディング

親コンポーネントと子コンポーネント間の双方向バインディングを活用するには、フォーム要素と比較して、より多くの設定が必要です。

ここでは、Appが初期カウント状態を設定しますが、カウンターのUIを更新およびレンダリングするためのロジックは、主にその子であるCounterにある例を示します。

// ./app.tsimport {Component} from '@angular/core';import {Counter} from './counter';@Component({  selector: 'app-root',  imports: [Counter],  template: `    <main>      <h1>Counter: {{ initialCount }}</h1>      <app-counter [(count)]="initialCount"></app-counter>    </main>  `,})export class App {  initialCount = 18;}
// './counter.ts';import {Component, model} from '@angular/core';@Component({  selector: 'app-counter',  template: `    <button (click)="updateCount(-1)">-</button>    <span>{{ count() }}</span>    <button (click)="updateCount(+1)">+</button>  `,})export class Counter {  count = model<number>(0);  updateCount(amount: number): void {    this.count.update((currentCount) => currentCount + amount);  }}

コンポーネント間の双方向バインディングを有効にする

上記の例をコアに分解すると、コンポーネントの双方向バインディングごとに、次のものが必要です。

子コンポーネントはmodelプロパティを含んでいる必要があります。

これは簡略化された例です。

// './counter.ts';import {Component, model} from '@angular/core';@Component({  /* Omitted for brevity */})export class Counter {  count = model<number>(0);  updateCount(amount: number): void {    this.count.update((currentCount) => currentCount + amount);  }}

親コンポーネントには、次のものが必要です。

  1. modelプロパティ名を双方向バインディング構文で囲む。
  2. プロパティまたはシグナルをmodelプロパティに割り当てる。

これは簡略化された例です。

// ./app.tsimport {Component} from '@angular/core';import {Counter} from './counter';@Component({  selector: 'app-root',  imports: [Counter],  template: `    <main>      <app-counter [(count)]="initialCount"></app-counter>    </main>  `,})export class App {  initialCount = 18;}