學習在 Angular 中 Data Binding 的機制。
Angular 提供了四種 Data Binding 的方式,他們的不同除了寫法上的不同,最主要是它們資料傳遞方向的不同。
有的是資料從元件傳到 DOM、有的是資料從 DOM 傳到元件、有的資料是可以在元件和 DOM 之間雙向傳遞。
1. Interpolation - 資料從元件傳遞到 DOM
這個在前幾天的文章中有提到過了,主要是用來將元件的資料呈現在 DOM 上,我們會用要被呈現在 DOM 上的屬性名稱用雙花括 (curly braces) 把它包起來。
--- app.component.ts ---
export class AppComponent {
name = 'Jasper';
}
--- app.component.html ---
<p> {{ name }} </p>
以上的範例,就可以將元件的 name 成員屬性內容插入到 p 段落裡面。
2. Property binding - 資料由元件流向指定 DOM 的屬性上
我們會利用這種方式,來將元件定義的成員屬性綁定到指定的 DOM 屬性上。
--- app.component.ts ---
export class AppComponent {
title = 'Jasper';
}
--- app.component.html ---
<input type="text" [placeholder]="title">
以上範例可以看到,我們把被指定 DOM 的屬性用中括號 (brackets) 把它包起來,並將元件的屬性綁定它到身上。
所以,以上的範例的結果就會像下面這樣
3. Event binding - 資料流方向為從 DOM 流向元件
這個情境就是,當你點擊畫面上的某個按鈕時,會觸發這個按鈕的 click 事件,而這個 click 事件會再觸發到元件定義的某個函式,這個觸發的機制就是資料流方向為從 DOM 流向元件。
--- app.component.html ---
<input #target (input)="search(target.value)">
--- app.component.ts ---
search(res) {
console.log(res);
}
以上的範例,就是當在 input 欄位輸入內容的時候,就會觸發到它的 input 事件,而它的 input 事件又會去觸發到元件定義的 search 函式,並同時把輸入的內容傳入進去,操作的結果會像下面這樣
4. Two-way data binding - 資料流會在元件和 DOM 之間傳遞
這個就是著名的雙向綁定~~
當你在 DOM 修改其內容的時候,也會連帶的修改到元件對應的屬性內容,反之,更改元件的屬性內容,就會連帶地修改到 DOM 的對應內容。
--- app.component.ts ---
title = 'Jasper'
--- app.component.html ---
<input type="text" [(ngModel)]="title">
以上這個範例會將該 input 欄位的 value 屬性值與元件的 title 屬性作雙向綁定。
Note:
在 Angular 中,在 input 或 textarea 使用 [(ngModel)] 的話,就會自動將這個雙向綁定的效果加到他們的 value 屬性上喔。
這邊做一個極度簡陋的計算機,來練習一下,上面提到的 Event binding 和 Property binding 這兩個 data-binding 的功能。
首先,是 html 的部分
<div>
<span>計算結果: </span>
<input type="text" [value]="currentProgress" />
<p>
<button type="button" (click)="getFirstNumber(3)">3</button>
<button type="button" (click)="getSecondtNumber(5)">5</button>
</p>
<p>
<button type="button" (click)="getOperation('+')" class="operator">
+
</button>
<button type="button" (click)="getOperation('=')">=</button>
</p>
<p>
<button (click)="clear()">Clear</button>
</p>
</div>
接下來,就是寫這些函式和屬性的內容,他們會寫在該元件的 ts 檔案中
export class AppComponent {
firstNumber = null;
secondNumber = null;
currentProgress = '';
getFirstNumber(first: number) {
this.firstNumber = first;
this.currentProgress += stringify(this.firstNumber);
}
getSecondtNumber(second: number) {
this.secondNumber = second;
this.currentProgress += stringify(this.secondNumber);
}
getOperation(op: string) {
switch (op) {
case '+':
this.currentProgress += '+';
return this.firstNumber;
case '=':
const result = this.firstNumber + this.secondNumber;
this.currentProgress = this.currentProgress + '=' + stringify(result);
return this.firstNumber;
}
}
clear() {
this.firstNumber = null;
this.secondNumber = null;
this.currentProgress = '';
}
}
上面的內容蠻單純的,就是將傳入的數字分別設給 firstNumber 和 secondNumber,並將它們轉型成字串設入 currentProgress 中,也因為我們有為 input 欄位的 value 屬性綁上 currentProgress 的屬性,所以,currentProgress 當下的內容就會即時被呈現在 input 欄位中囉~
操作結果如下
這邊做個總結
Note:
這邊想要特別註明一下,這四種 Data Binding 的方式,只有 interpolation 的時候,也就是想要直接將元件的屬性內容呈現在畫面上才會需要將屬性用雙花括把它包起來,另外三種就直接寫上屬性名稱就好,不要搞錯了,我自己是很常搞混啦....XD