Angular2+ 雙向資料繫結
阿新 • • 發佈:2019-01-06
我們經常需要顯示資料屬性,並在使用者作出更改時更新該屬性。
在元素層面上,既要設定元素屬性,又要監聽元素事件變化。
Angular 為此提供一種特殊的雙向資料繫結語法:[(x)]
。 [(x)]
語法結合了屬性繫結的方括號[x]
和事件繫結的圓括號(x)
。
當一個元素擁有可以設定的屬性x
和對應的事件xChange
時,解釋[(x)]
語法就容易多了。 下面的SizerComponent
符合這個模式。它有size
屬性和伴隨的sizeChange
事件:
import { Component, EventEmitter, Input, Output } from '@angular/core'; @Component({ selector:'app-sizer', template: ` <div> <button (click)="dec()" title="smaller">-</button> <button (click)="inc()" title="bigger">+</button> <label [style.font-size.px]="size">FontSize: {{size}}px</label> </div>` }) export class SizerComponent { @Input() size: number| string; @Output() sizeChange = new EventEmitter<number>(); dec() { this.resize(-1); } inc() { this.resize(+1); } resize(delta: number) { this.size = Math.min(40, Math.max(8, +this.size + delta)); this.sizeChange.emit(this.size); } }
size
的初始值是一個輸入值,來自屬性繫結。(譯註:注意size
前面的@Input
)
點選按鈕,在最小/最大值範圍限制內增加或者減少size
。 然後用調整後的size
觸發sizeChange
事件。<app-sizer [(size)]="fontSizePx"></app-sizer> <div [style.font-size.px]="fontSizePx">Resizable Text</div>雙向繫結語法實際上是屬性繫結和事件繫結的語法糖。 Angular將
SizerComponent
的繫結分解成這樣:<app-sizer [size]="fontSizePx" (sizeChange)="fontSizePx=$event"></app-sizer>
$event變數包含了SizerComponent.sizeChange事件的荷載。 當用戶點選按鈕時,Angular 將$event賦值給AppComponent.fontSizePx。
顯然,比起單獨繫結屬性和事件,雙向資料繫結語法顯得非常方便。
我們希望能在像<input>和<select>這樣的 HTML 元素上使用雙向資料繫結。 可惜,原生 HTML 元素不遵循x值和xChange事件的模式。
幸運的是,Angular 以 NgModel 指令為橋樑,允許在表單元素上使用雙向資料繫結。
在個人封裝模組元件的時候,需要注意:輸入引數 x 和 輸出方法xChange對應,不然雙向繫結也不會成功
在angular中操作的屬性是 DOM屬性 property 而不是操作的HTML屬性 attribute
[(ngModel)]內幕
<input [ngModel]="currentHero.name" (ngModelChange)="currentHero.name=$event">--strictNullChecks 嚴格空值檢查 TypeScript就會確保不存在意料之外的null或undefined。