開発覚書はてな版

個人的な開発関連の備忘録

【Angular】双方向バインディングの実装

概要

自作コンポーネントで双方向バインディングの実装の仕方を記載します。
※今回はControlValueAccessorは未使用で実装します。

下記のような設定をします。

  • 自作コンポーネント
    • @Inputでプロパティを定義する。
    • @OutputでEventEmitterを定義する。EventEmitterの型は@Inputの型と同じものとする。
    • @Output側のプロパティ名を@Inputのプロパティ名 + Changeにする。
      例)@Inputがvalueだった場合、@OutputはvalueChange
    • 自作コンポーネント内の処理で@Output側のEventEmitter.emit処理を実行することで、値が呼び出し側に伝搬する。
  • 呼び出し側コンポーネント
    • [(双方向対象のプロパティ)]="呼び出し側プロパティ"のように呼び出す。

動作環境

  • TypeScript 2.9.x
  • Angular 6.1.x

サンプルソース

custom-list.component.ts
import { Component, Input, Output, EventEmitter } from '@angular/core';

@Component({
  selector: 'custom-list',
  template: `
    <ul>
      <li *ngFor="let num of list"
        (click)="changeValue(num)" [style.background-color]="num === value ? 'yellow' : 'white'">
        {{ num }}
      </li>
    </ul>
  `
})
export class CustomListComponent {

  /** 表示リスト */
  list: number[] = [1, 2, 3, 4, 5];

  /** 選択値 */
  @Input()
  value: number = 0;

  /** 選択値変更 */
  @Output()
  valueChange = new EventEmitter<number>();

  /**
   * 選択値変更処理
   * @param num
   */
  changeValue(num: number): void {
    this.value = num;
    this.valueChange.emit(num);
  }
}
app.component.ts
import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  template: `
    <h2>TwoWay Binding Sample</h2>
    <custom-list [(value)]="num"></custom-list>
    <div>num: {{ num }}</div>
  `
})
export class AppComponent {
  num: number = 2;
}
実行結果

f:id:kakkoya:20180820204217g:plain

サンプルソース一式

github.com