angular模板與資料繫結
一. 資料顯示
1. 使用插值表示式顯示元件屬性
template: `
<h1>{{title}}</h1>
<h2>My favorite hero is: {{myHero}}</h2>
`
JavaScript 中那些具有或可能引發副作用的表示式是被禁止的,包括:
- 賦值 (=, +=, -=, ...)
- new運算子
- 使用;或,的鏈式表示式
- 自增或自減操作符 (++和--)
模板是包在 ECMAScript 2015 反引號 (
) 中的一個多行字串。 反引號 (
) — 注意,不是單引號 (') — 允許把一個字串寫在多行上, 使 HTML 模板更容易閱讀。
注意,我們沒有呼叫 new 來建立AppComponent類的例項,是 Angular 替我們建立了它。
export class AppCtorComponent {
title: string;
myHero: string;
constructor() {
this.title = 'Tour of Heroes';
this.myHero = 'Windstorm';
}
}
2.使用ngFor顯示陣列屬性
template: ` <h1>{{title}}</h1> <h2>My favorite hero is: {{myHero}}</h2> <p>Heroes:</p> <ul> <li *ngFor="let hero of heroes"> {{ hero }} </li> </ul> `
ngFor用於顯示一個“陣列”, 但ngFor可以為任何可迭代的 (iterable) 物件重複渲染條目。
4. 使用NgForOf顯示陣列屬性
- index: number: The index of the current item in the iterable.
- count: number:
- first: boolean: True when the item is the first item in the iterable.
- last: boolean: True when the item is the last item in the iterable.
- even: boolean: True when the item has an even index in the iterable.
- odd: boolean: True when the item has an odd index in the iterable.
<li *ngFor="let user of userObservable | async as users; index as i; first as isFirst">
{{i}}/{{users.length}}. {{user}} <span *ngIf="isFirst">default</span>
</li>
3. 通過 NgIf 進行條件顯示
<p *ngIf="heroes.length > 3">There are many heroes!</p>
Angular 並不是在顯示和隱藏這條訊息,它是在從 DOM 中新增和移除這個段落元素。 這會提高效能,特別是在一些大的專案中有條件地包含或排除一大堆帶著很多資料繫結的 HTML 時。
ngIf指令通常會用來防範空指標錯誤。
4. ngSwitch
<container-element [ngSwitch]="switch_expression">
<some-element *ngSwitchCase="match_expression_1">...</some-element>
<some-element *ngSwitchCase="match_expression_2">...</some-element>
<some-other-element *ngSwitchCase="match_expression_3">...</some-other-element>
<ng-container *ngSwitchCase="match_expression_3">
<!-- use a ng-container to group multiple root nodes -->
<inner-element></inner-element>
<inner-other-element></inner-other-element>
</ng-container>
<some-element *ngSwitchDefault>...</some-element>
</container-element>
二. 模板
1. 插值表示式
<h3>
{{title}}
<img src="{{heroImageUrl}}" style="height:30px">
//或者
<img [src]="heroImageUrl" style="height:30px">
</h3>
Angular 對所有雙花括號中的表示式求值,把求值的結果轉換成字串,並把它們跟相鄰的字串字面量連線起來。最後,把這個組合出來的插值結果賦給元素或指令的屬性。
2. 模板表示式,表示式上下文
表示式的上下文可以包括元件之外的物件。 比如模板輸入變數 (let hero)和模板引用變數(#heroInput)就是備選的上下文物件之一。
<div *ngFor="let hero of heroes">{{hero.name}}</div>
<input #heroInput> {{heroInput.value}}
表示式中的上下文變數是由模板變數、指令的上下文變數(如果有)和元件的成員疊加而成的。 如果我們要引用的變數名存在於一個以上的名稱空間中,那麼,模板變數是最優先的,其次是指令的上下文變數,最後是元件的成員。
3. 模板語句
模板語句用來響應由繫結目標(如 HTML 元素、元件或指令)觸發的事件。 模板語句將在事件繫結一節看到,它出現在=號右側的引號中,就像這樣:(event)="statement"。
語句上下文可以引用模板自身上下文中的屬性。 在下面的例子中,就把模板的$event物件、模板輸入變數 (let hero)和模板引用變數 (#heroForm)傳給了元件中的一個事件處理器方法。
<button (click)="onSave($event)">Save</button>
<button *ngFor="let hero of heroes" (click)="deleteHero(hero)">{{hero.name}}</button>
<form #heroForm (ngSubmit)="onSubmit(heroForm)">
</form>
4. 資料繫結
資料方向 | 語法 | 繫結型別 |
---|---|---|
單向:從資料來源到檢視目標 | {{expression}} [target]="expression"bind-target="expression" | 插值表示式 Property Attribute 類 樣式 |
單向:從檢視目標 到資料來源 | (target)="statement"ontarget="statement" | 事件 |
雙向 | [(target)]="expression"bindon-target="expression" | 雙向 |
HTML attribute 與 DOM property 的對比 要想理解 Angular 繫結如何工作,重點是搞清 HTML attribute 和 DOM property 之間的區別。
attribute 是由 HTML 定義的。property 是由 DOM (Document Object Model) 定義的。
少量 HTML attribute 和 property 之間有著 1:1 的對映,如id。 有些 HTML attribute 沒有對應的 property,如colspan。 有些 DOM property 沒有對應的 attribute,如textContent。 大量 HTML attribute看起來對映到了property…… 但卻不像我們想的那樣! 最後一類尤其讓人困惑…… 除非我們能理解這個普遍原則:
attribute 初始化 DOM property,然後它們的任務就完成了。property 的值可以改變;attribute 的值不能改變。
例如,當瀏覽器渲染時,它將建立相應 DOM 節點, 其value property 被初始化為 “Bob”。
當用戶在輸入框中輸入 “Sally” 時,DOM 元素的value property 變成了 “Sally”。 但是這個 HTML value attribute 保持不變。如果我們讀取 input 元素的 attribute,就會發現確實沒變: input.getAttribute('value') // 返回 "Bob"。
HTML attribute value指定了初始值;DOM value property 是當前值。
disabled attribute 是另一個古怪的例子。按鈕的disabled property 是false,因為預設情況下按鈕是可用的。 當我們新增disabled attribute 時,只要它出現了按鈕的disabled property 就初始化為true,於是按鈕就被禁用了。
新增或刪除disabled attribute會禁用或啟用這個按鈕。但 attribute 的值無關緊要,這就是我們為什麼沒法通過 仍被禁用這種寫法來啟用按鈕。
設定按鈕的disabled property(如,通過 Angular 繫結)可以禁用或啟用這個按鈕。 這就是 property 的價值。
就算名字相同,HTML attribute 和 DOM property 也不是同一樣東西。
模板繫結是通過 property 和事件來工作的,而不是 attribute。
5. 屬性繫結 ( [屬性名] )
<img [src]="heroImageUrl">
<button [disabled]="isUnchanged">Cancel is disabled</button>
<div [ngClass]="classes">[ngClass] binding to the classes property</div>
<goods-detail [goods]="currentGood"></goods-detail>
樣式繫結
class
<p class="bg-red" [class]="'div-css'">
這個時候div-css 會完全覆蓋bg-red的樣式。
newcss='div-css'; <p class="bg-red" [class]="newcss">
這個時候newcss屬性部位空時, 會完全覆蓋bg-red的樣式。
<div [class.cssName]="expression">The class binding is special</div>
當想要同時新增或移除多個 CSS 類時,NgClass指令可能是更好的選擇。
<div [ngClass]="{'special': isSpecial}"></div> //多個樣式選擇 this.currentClasses = { 'saveable': this.canSave, 'modified': !this.isUnchanged, 'special': this.isSpecial }; <div [ngClass]="currentClasses">This div is initially saveable, unchanged, and special</div>
style
<button [style.color]="isSpecial ? 'red': 'green'">Red</button>
<button [style.background-color]="canSave ? 'cyan': 'grey'" >Save <button [style.font-size.em]="isSpecial ? 3 : 1" >Big <button [style.font-size.%]="!isSpecial ? 150 : 50" >Small ```
如果要同時設定多個內聯樣式,NgStyle指令可能是更好的選擇。
```
this.currentStyles = {
'font-style': this.canSave ? 'italic' : 'normal',
'font-weight': !this.isUnchanged ? 'bold' : 'normal',
'font-size': this.isSpecial ? '24px' : '12px'
};
<div [ngStyle]="currentStyles"></div>
```
NgModel
在使用ngModel指令進行雙向資料繫結之前,我們必須匯入FormsModule並把它新增到Angular模組的imports列表中。
``` import { FormsModule } from '@angular/forms'; ```
6.模板引用變數 ( #var )
模板引用變數通常用來引用模板中的某個DOM元素,它還可以引用Angular元件或指令或Web Component。
可以通過模板引用變數 呼叫子元件內部的方法。
<button id="btn01" #btn (click)="show(btn)">click...</button>
<h1>{{btn.id}}</h1>
模板引用變數的作用範圍是整個模板。 不要在同一個模板中多次定義同一個變數名,否則它在執行期間的值是無法確定的。
7. 模板表示式操作符---安全導航操作符 ( ?. ) 和空屬性路徑
用NgIf程式碼環繞它來解決這個問題。
<div *ngIf="nullHero">The null hero's name is {{nullHero.name}}</div>
或者可以嘗試通過&&來把屬性路徑的各部分串起來,讓它在遇到第一個空值的時候,就返回空。
The null hero's name is {{nullHero && nullHero.name}}
Angular 安全導航操作符 (?.) 是在屬性路徑中保護空值的更加流暢、便利的方式。 表示式會在它遇到第一個空值的時候跳出。 顯示是空的,但應用正常工作,而沒有發生錯誤。
The null hero's name is {{nullHero?.name}}