Angular2では <input [(ngModel)]="firstName">
と書けば、これを利用してるページでの currentHero.firstName
との双方向バインディング(two-way binding)が出来ます。
つまり、スクリプト側で値を変えたら反映されるし、View(つまりHTMLというかDOMというかブラウザ上というか)側で値を変えても、もちろん反映されます。
こういうの、標準の <input>
タグとかには Angular側が組み込みで用意してくれているけれども、自作したカスタムコンポーネントではどうする?
答え
@Input() value
を作ってるならば
@Output() valueChange = new EventEmitter();
と、同名+ChangeのEventEmitterを作るだけでよい。
そうすると、[(value)]
で双方向バインディング出来ます。
ありがちなミス
うまく動かないときは Change"d"
になっていないか確認してください。
valueChanged
など、 Changed
では双方向バインディングできません。
実例
import { Component, EventEmitter, Input, Output } from '@angular/core';
@Component({
selector: 'input-name',
template: `
<div>
<label>あなたのお名前なんですか?</label>
<input [value]="name" (change)="change($event.target.value)"></input>
<button (click)="clear()">クリア</button>
</div>`
})
export class InputNameComponent {
@Input() value: string; // 受け口。 <input-name value="123">と書かれると123が代入される
@Output() valueChange = new EventEmitter<string>(); // 出力口。
change(value) { //値が変化した
this.value = value
this.valueChange.emit(this.value)
}
clear() { //入力値をクリア
this.value = ""
this.valueChange.emit(this.value)
}
}
利用側
<!-- シンプルに書ける -->
<input-name [(value)]="firstName"></input-name>
<!-- とはいえ、上の書き方はエラー時に混乱しやすいので、こんな風に書いたほうが分かりやすいかも -->
<input-name [value]="firstName" (valueChange)="firstName=$event"></input-name>
分かってれば簡単だった。