Angular2 模板與綁定--互動的根本
- 2016-12-20
- Liu, An-Chi 劉安齊
先前在說明 Angular 2 的架構時有約略提到數據綁定的方式,接著就讓我們學學如何寫模板 (template) ,如何顯示數據和事件綁定。那為甚麼要學模板的寫法呢?以及模板到底可以幹嗎?我們看到的網站都是 HTML 的顯示,但是 HTML 是死的,要做出互動傳統上必須靠 JavaScript,但是 JS 控制 HTML
數據綁定小複習
- Interpolation
- One Way Binding
- Two Way Binding
- Event Binding
概觀
語法
在 Anugular 2 中:
- One Way Binding:從看到的目標綁定數據來源用的是:
- (target) = "statement"
- on-target = "statement"
- One Way Binding:從數據來源綁定看到的目標用的是:
- [target] = "expression"
- bind-target = "expression"
- Two Way Binding:數據端跟視覺端可以互相綁定用的是:
- [(target)] = "expression"
- bindon-target = "expression"
範例
我們可以再 Component 中宣告自己的標籤
<!-- Normal HTML -->
<div class="special">Mental Model</div>
<!-- Wow! A new element! -->
<hero-detail></hero-detail>
Component 中的 isValid
為 false
的時候按鈕鎖住。
<!-- Bind button disabled state to `isValid` property -->
<button [disabled]="!isValid">Save</button>
可以直接綁定連結
<img [src]="imageUrl">
可以綁定特性
<div [ngClass]="classes">[ngClass] binding to the classes property</div>
綁定 Attribute、class、style
用途
當我們想針對 HTML 的屬性、類別、風格做改變時,透過 Angular 特性 (property) 綁定的方式,可以輕鬆一據綁定的數據做改變,比方說想要達成按下按鈕顏色改變,就可以透過這種方式,比起傳統的方式,增加不少便利性。
Attribute binding (屬性綁定)
針對 HTML 物件的屬性作綁定,可以依據綁定的變數數值變化而改變屬性。
<table border=1>
<!-- expression calculates colspan=2 -->
<tr><td [attr.colspan]="1 + 1">One-Two</td></tr>
<tr><td>Five</td><td>Six</td></tr>
</table>
Class binding
當綁定的數值為 true
時顯示 class
,false
移除 class
<!-- toggle the "special" class on/off with a property -->
<div [class.special]="isSpecial">The class binding is special</div>
<!-- binding to class.special
trumps the class attribute –>
<div class="special"
[class.special]="!isSpecial">This one is not so special</div>
Style binding
一樣的邏輯也可以用在 style
<button [style.color] = "isSpecial ? 'red': 'green'">Red</button>
<button [style.background-color]="canSave ? 'cyan': 'grey'" >Save</button>
事件綁定 (Event binding)
一般的事件綁定
tempalte:
<button (click)="onSave()">Save</button>
Component:
@Component({
...
})
export class AppComponent {
onSave(): void{
...
}
}
這種一般的用法,可以拿來做按鈕呼叫 API 提交表單等等,不需要做 HTML Element 變化的互動。
也可以是自訂的事件綁定,這時候我們用 Angular EventEmitter
我們這樣定義觸發事件:
deleteRequest = new EventEmitter<Hero>();
delete() {
this.deleteRequest.emit(this.hero);
}
模板:
<div>
...
<button (click)="delete()">Delete</button>
...
</div>
<hero-detail (deleteRequest)="deleteHero($event)" [hero]="currentHero"></hero-detail>
當 delete()
執行,會觸發 deleteRequest
產生的 EvevntEmitter
物件製造出 Hero
,接者 <hero-detail>
會跟著 deleteRequest
事件觸發的改變而改變。
數據綁定
Interpolation
基本就是在 html
template 裡面加上 { { } }
,中間包住想要顯示的變數,而變數則是宣告在 app.component.ts
裡面。
來看看範例:
// app.component.ts
import {Component} from 'angular2/core';
@Component({
selector: 'my-app',
templateUrl: 'app.component.html',
styleUrls: ['app.component.css']
})
export class AppComponent {
title = 'Tour of Heroes';
myHero = 'Windstorm';
}
// app.component.html
<h1>{{title}}</h1>
<h2>My favorite hero is: {{myHero}}</h2>
會顯示成這樣:
因為是在同個 Component,當 Angular 在 Template 中偵測到 { { } }
的時候, Class 裡的變數會直接被放到 { { } }
裡面。當變數值發生改變時也會跟著更新顯示,數值重新渲染顯示是發生在與視圖相關的某些異步事件之後,例如點擊、勾選、呼叫 XHR。
還可以拿來這樣用:
<!-- "The sum of 1 + 1 is 2" -->
<p>The sum of 1 + 1 is {{1 + 1}}</p>
Two Way Binding
顧名思義,就是前後都能彼此控制對方,更白話一點就是程式可以控制顯示,顯示的地方也可以利用按鈕、輸入等方式改變數據。
可能就會長得像這樣;
<my-sizer [(size)]="fontSizePx"></my-sizer>
<div [style.font-size.px]="fontSizePx">Resizable Text</div>
my-sizer
雙向綁定,不管是數據來源改變還是介面由使用者改變,而下面的的 div
則會受到改變。
NgModal
當有 Input
、Select
的時候 NgModal
可以有效連結綁定 Component 的數據。
直接來看看範例吧:
<div>
<h4>Select Account</h4>
<select [(ngModel)]="selectedAccount" (ngModelChange)="selectAccount()">
<option *ngFor="let account of accounts" [ngValue]="account">{{account.name}}</option>
</select>
</div>
*ngFor
會顯示 accounts: array
中所有的 account
,被選取的選項,透過 [ngValue]
回傳值,因為<select>
已經和 [(ngModal)]
綁定,所以 [(ngModal)]
得到 [ngValue]
的值,並和 Component 中的 selectedAccount
做雙向綁定。
甚麼意思呢,就是說你拉下選單選某個選項時候, Component 中的 selectedAccount
也跟著選項改變他的值。