modelシグナルによる双方向バインディング

inputシグナルによるコンポーネントへのデータ受け渡しを学習したところで、Angularのmodel() APIを使った双方向バインディングについて見ていきましょう。modelシグナルは、チェックボックス、スライダー、カスタムフォームコントロールなど、コンポーネントが値を受け取ると同時に更新する必要があるUIコンポーネントに最適です。

このアクティビティでは、親と同期を保ちながら自身の状態を管理するカスタムチェックボックスコンポーネントを作成します。


  1. modelシグナルでカスタムチェックボックスを設定する

    custom-checkboxコンポーネントに、親の値を送受信できるmodelシグナルを作成します。

    // Add imports for model signalsimport {Component, model, input, ChangeDetectionStrategy} from '@angular/core';// Model signal for two-way bindingchecked = model.required<boolean>();// Optional input for labellabel = input<string>('');

    読み取り専用のinput()シグナルとは異なり、model()シグナルは読み取りと書き込みの両方が可能です。

  2. チェックボックスのテンプレートを作成する

    クリックに応答し、自身のモデルを更新するチェックボックスのテンプレートを作成します。

    <label class="custom-checkbox">  <input type="checkbox" [checked]="checked()" (change)="toggle()" />  <span class="checkmark"></span>  {{ label() }}</label>

    コンポーネントはmodelシグナルから読み取り、それを更新するメソッドを持っています。

  3. toggleメソッドを追加する

    チェックボックスがクリックされたときにmodelシグナルを更新するtoggleメソッドを実装します。

    toggle() {  // This updates BOTH the component's state AND the parent's model!  this.checked.set(!this.checked());}

    子コンポーネントがthis.checked.set()を呼び出すと、変更は自動的に親に伝播されます。これがinput()シグナルとの主な違いです。

  4. 親で双方向バインディングを設定する

    まず、app.ts内のmodelシグナルプロパティとメソッドのコメントを解除します。

    // Parent signal modelsagreedToTerms = model(false);enableNotifications = model(true);// Methods to test two-way bindingtoggleTermsFromParent() {  this.agreedToTerms.set(!this.agreedToTerms());}resetAll() {  this.agreedToTerms.set(false);  this.enableNotifications.set(false);}

    次に、テンプレートを更新します。

    パート1. チェックボックスのコメントを解除し、双方向バインディングを追加します。

    • 最初のチェックボックスの___ADD_TWO_WAY_BINDING___[(checked)]="agreedToTerms"に置き換えます。
    • 2番目のチェックボックスの___ADD_TWO_WAY_BINDING___[(checked)]="enableNotifications"に置き換えます。

    パート2. ???プレースホルダーを@ifブロックに置き換えます。

    @if (agreedToTerms()) {  Yes} @else {  No}@if (enableNotifications()) {  Yes} @else {  No}

    パート3. ボタンにクリックハンドラーを追加します。

    <button (click)="toggleTermsFromParent()">Toggle Terms from Parent</button><button (click)="resetAll()">Reset All</button>

    [(checked)]構文は双方向バインディングを作成します。データはコンポーネントに流れ込み、変更はシグナル自体を参照するイベントを発行することで親に流れ戻ります。このとき、シグナルゲッターを直接呼び出すことは_ありません_。

  5. 双方向バインディングをテストする

    アプリケーションを操作して、双方向バインディングの動作を確認します。

    1. チェックボックスをクリックする - コンポーネントは自身の状態を更新し、親に通知します。
    2. 「Toggle Terms from Parent」をクリックする - 親の更新がコンポーネントに伝播されます。
    3. 「Reset All」をクリックする - 親が両方のモデルをリセットし、コンポーネントが自動的に更新されます。

    親と子の両方が共有状態を更新でき、両方とも自動的に同期を保ちます!

完璧です!modelシグナルがどのように双方向バインディングを可能にするかを学びました。

  • Modelシグナル - 読み取りと書き込みの両方が可能な値にはmodel()model.required()を使用します。
  • 双方向バインディング - 親シグナルを子モデルにバインドするには[(property)]構文を使用します。
  • UIコンポーネントに最適 - チェックボックス、フォームコントロール、および自身の状態を管理する必要があるウィジェット。
  • 自動同期 - 手動のイベント処理なしで、親と子が同期を保ちます。

model()input()の使い分け:

  • データが下方向にのみ流れる場合(表示データ、設定)はinput()を使用します。
  • 自身の値を更新する必要があるUIコンポーネント(フォームコントロール、トグル)にはmodel()を使用します。

次のレッスンでは、サービスでのシグナルの使用について学びます!