top
Loading...
Angular 2 模板語法

Angular 2 模板語法

前面幾個章節我們已經接觸了 Angular 的模板,本文我們將具體介紹 Angular 的語法使用。

模板扮演的是一個視圖的角色,簡單講就是展示給用戶看的部分。

  • HTML
  • 插值表達式
  • 模板表達式
  • 模板語句
  • 綁定語法
  • 屬性綁定
  • HTML 屬性、 class 和 style 綁定
  • 事件綁定
  • 使用 NgModel 進行雙向數據綁定
  • 內置指令
  • * 與 <template>
  • 模板引用變量
  • 輸入輸出屬性
  • 模板表達式操作符

HTML

HTML 是 Angular 模板的"語言",除了 <script> 元素是被禁用的外 ,其他 HTML 元素都是支持的,例如:

<h1>我的第一個 Angular 應用</h1>


插值表達式

插值表達式的語法格式為:{{ ... }}

插值表達式可以把計算的字符串插入HTML中,也可以作為屬性值來使用。

<h3> {{title}} <img src="{{imageUrl}}" style="height:30px"> </h3>

模板表達式

{{ ... }} 里頭其實就是一個模板表達式,Angular 會對其進行求值併轉化為字符串輸出。

以下實例是兩個數相加:

<!-- "The sum of 1 + 1 is 2" --> <p>The sum of 1 + 1 is {{1 + 1}}</p>

我們可以使用 getVal() 來獲取這個表達式的值:

<div class="example"> <div class="example_code"> [mycode3 type="html"] <!-- "4" --> <p>{{1 + 1 + getVal()}}</p>

模板表達式類似 JavaScript 的語言,很多 JavaScript 表達式也是合法的模板表達式,但不是全部。

以下 JavaScript 表達式是禁止的:

  • 賦值表達式(=+=-=...)
  • new操作符
  • 帶有;或者'的連接表達式
  • 自增和自減操作(++--) 其他與Javascript語法不同的值得注意的包括:
  • 不支持位運算符(|&
  • 模板表達式的操作符,如|?.等,被賦予了新的含義

屬性綁定

模板的屬性綁定可以把視圖元素的屬性設置為模板表達式 。

最常用的屬性綁定是把元素的屬性設置為組件中屬性的值。 下面這個例子中, image 元素的 src 屬性會被綁定到組件的 imageUrl 屬性上:

<img [src]="imageUrl">

當組件為 isUnchanged( 未改變 ) 時禁用一個按鈕:

<button [disabled]="isUnchanged">按鈕是禁用的</button>

設置指令的屬性:

<div [ngClass]="classes">[ngClass]綁定到classes 屬性</div>

設置一個自定義組件的屬性(這是父子組件間通訊的重要途徑):

<user-detail [user]="currentUser"></user-detail>

HTML 屬性(Attribute)、 class 和 style 綁定

模板語法為那些不太適合使用屬性綁定的場景提供了專門的單向數據綁定形式。

屬性(Attribute)、綁定

當元素沒有屬性可綁的時候,使用HTML標籤屬性(Attribute)綁定。

考慮 ARIA, SVG 和 table 中的 colspan/rowspan 等屬性(Attribute) 。它們是純粹的屬性 。 它們沒有對應的屬性可供綁定。

以下實例會報錯:

<tr><td colspan="{{1 + 1}}">Three-Four</td></tr>

我們會得到這個錯誤:

Template parse errors:
Can't bind to 'colspan' since it isn't a known native property
模板解析錯誤:不能綁定到'colspan',因為它不是已知的原生屬性

正如提示中所說, <td> 元素沒有 colspan 屬性。 但是插值表達式和屬性綁定只能設置 屬性 ,而不是 Attribute,所以需HTML標籤 Attribute 綁定來創建和綁定類似的Attribute。

HTML標籤特性綁定在語法上類似於屬性綁定,但中括號中的部分不是一個元素的屬性名,而是由一個attr.的前綴和HTML標籤屬性的名稱組成,然後通過一個能求值為字符串的表達式來設置HTML標籤屬性的值。如:

<table border=1> <tr><td [attr.colspan]="1 + 1">One-Two</td></tr> <tr><td>Five</td><td>Six</td></tr> </table>

css類綁定

借助 CSS 類綁定 ,我們可以從元素的 class 屬性上添加和移除 CSS 類名。

CSS 類綁定在語法上類似於屬性綁定。但方括號中的部分不是一個元素的屬性名,而是包括一個 class 前綴,緊跟著一個點 (.) ,再跟著 CSS 類的名字組成。 其中後兩部分是可選的。例如: [class.class-name]

下面的例子展示了如何通過css類綁定類添加和移除"special"類:

<!-- 標准HTML樣式類設置 --> <div class="bad curly special">Bad curly special</div> <!-- 通過綁定重設或覆蓋樣式類 --> <div class="bad curly special" [class]="badCurly">Bad curly</div> <!-- 通過一個屬性值來添加或移除special樣式類 --> <div [class.special]="isSpecial">這個樣式比較特殊</div>

style樣式綁定

通過樣式綁定,可以設置內聯樣式。樣式綁定語法上類似於屬性綁定,但中括號里面的部分不是一個元素的屬性名,樣式綁定包括一個style.,緊跟著css樣式的屬性名,例如:[style.style-property]。

<button [style.color] = "isSpecial ? 'red': 'green'">紅色</button> <button [style.background-color]="canSave ? 'cyan': 'grey'" >保存</button> <!-- 帶有單位的樣式綁定 --> <button [style.font-size.em]="isSpecial ? 3 : 1" ></button> <button [style.font-size.%]="!isSpecial ? 150 : 50" ></button>

樣式屬性可以是中線命名法(font-size),也可以是駝峰是命名法(fontSize)。


事件綁定

在事件綁定中,Angular通過監聽用戶動作,比如鍵盤事件、鼠標事件、觸屏事件等來響應相對應的數據流向-從視圖目標到數據源。

事件綁定的語法是由等號左側小括號內的 目標事件 和右側引號中的 模板聲明 組成。

比如下面這個例子,是事件綁定監聽按鈕的點擊事件。只要點擊鼠標,都會調用組件的 onSave()方法。

<button (click)="onSave()">保存</button>

圓括號中的名稱 ——比如 (click) ——標記出了目標事件。在下面這個例子中,目標是按鈕的 click 事件。

<button (click)="onSave()">Save</button>

也可以使用on- 前綴的形式:

<button on-click="onSave()">On Save</button>

使用 NgModel 進行雙向數據綁定

當開發數據輸入表單時,期望的結果是既能將組件的數據顯示到表單上,也能在用戶修改時更新組件的數據。

以下是一個通過 [(NgModel)] 來實現雙向綁定:

<input [(ngModel)]="currentUser.firstName">

[]實現了數據流從組件到模板,()實現了數據流從模板到組件,兩者一結合[()]就實現了雙向綁定。

使用前綴形式的語法:

<input bindon-ngModel="currentUser.firstName">

內置指令

Angular 的內置指令有 NgClass、NgStyle、NgIf、NgFor、NgSwitch等。

NgClass

通過綁定到 NgClass 動態添加或刪除 CSS 類。

<div [style.font-size]="isSpecial ? 'x-large' : 'smaller'" > 這個div是大號的。 </div>

NgStyle

NgStyle 通過把它綁定到一個key:value控製對象的形式,可以讓我們同時設置很多內聯樣式。

setStyles() { let styles = { // CSS屬性名 'font-style': this.canSave ? 'italic' : 'normal', // italic 'font-weight': !this.isUnchanged ? 'bold' : 'normal', // normal 'font-size': this.isSpecial ? '24px' : '8px', // 24px }; return styles; }

通過添加一個NgStyle屬性綁定,讓它調用setStyles,併據此來設置元素的樣式:

<div [ngStyle]="setStyles()"> 這個div的樣式是italic, normal weight, 和extra large (24px)。 </div>

NgIf

通過把NgIf指令綁定到一個真值表達式,可以把一個元素及其子元素添加到DOM樹上。

<div *ngIf="currentUser">Hello,{{currentUser.firstName}}</div>

相反,綁定到一個假值表達式將從DOM樹中移除該元素及其子元素。如:

<!-- 因為isActive的值為false,所以User Detail不在DOM樹種--> <user-detail *ngIf="isActive"></user-detail>

NgSwitch

當需要從一組可能的元素樹中根據條件顯示其中一個時,就需要NgSwitch了。Angular將只把選中的元素添加進DOM中。如:

<span [ngSwitch]="userName"> <span *ngSwitchCase="'張三'">張三</span> <span *ngSwitchCase="'李四'">李四</span> <span *ngSwitchCase="'王五'">王五</span> <span *ngSwitchCase="'趙六'">趙六</span> <span *ngSwitchDefault>龍大</span> </span>

把作為父指令的NgSwitch綁定到一個能返回開關值的表達式,例子中這個值是字符串,但它可以是任何類型的值。父指令NgSwitch控製一組<span>子元素。每個<span>或者掛在一個匹配值的表達式上,或者被標記為默認情況。任何時候,這些span中最多只有一個會出現在DOM中。如果這個span的匹配值和開關值相等,Angular2就把這個<span>添加DOM中。如果沒有任何span匹配上,Angular2就會把默認的span添加到DOM中。Angular2會移除併銷毀所有其他的span。

三個相互合作的指令:

  • ngSwitch:綁定到一個返回開關值的表達式
  • ngSwitchCase:綁定到一個返回匹配值的表達式
  • ngSwitchDefault:一個用於標記默認元素的屬性 注意:不要再ngSwitch前使用*,而應該用屬性綁定,但ngSwitchCase和ngSwitchDefault前面要放*

NgFor

當需要展示一個由多個條目組成的列表時就需要這個指令了。如下面這個例子,就是在一個HTML塊上應用NgFor。

<div *ngFor="let user of users">{{user.fullName}}</div>

NgFor也可以應用在一個組件元素上,如:

<user-detail *ngFor="let user of users" [user]="user"></user-detail>

ngFor指令支持一個可選的index索引,在疊代過程中會從0增長到數組中的長度。

可以通過模板輸入變量來捕獲這個index,併應用在模板中。下面的例子就把index捕獲到了一個名為i的變量中。

<div *ngFor="let user of users; let i=index">{{i + 1}} - {{user.fullName}}</div>

NgForTrackBy

ngFor 指令有時候會性能較差,特別是在大型列表中。 對一個條目的一點小更改、移除或添加,都會導致級聯的 DOM 操作。

比如,當通過重新從服務器來刷新通訊錄,刷新後的列表可能包含很多(如果不是全部的話)以前顯示過的聯系人。但在Angular看來,它不知道哪些是以前就存在過的,只能清理舊列表、捨棄那些DOM元素,併用新的DOM元素來重建一個新列表。

解決這個問題,可以通過追蹤函數來避免這種折騰。追蹤函數會告訴Angular:我們知道兩個具有相同user.id的對象是同一個聯系人。如:

trackByUsers(index: number, user: User){return user.id}

然後,把NgForTrackBy指令設置為那個追蹤函數:

<div *ngFor="let user of users; trackBy:trackByUsers">({{user.id}}) {{user.fullName}}</div>

追蹤函數不會排除所有DOM更改。如果用來判斷是否為同一個聯系人的屬性變化了,就會更新DOM元素,反之就會留下這個DOM元素。列表界面就會變得比較更加平滑,具有更好的響應傚果。


模板引用變量

模板引用變量是模板中對 DOM 元素或指令的引用。

它能在原生 DOM 元素中使用,也能用於 Angular 組件——實際上,它可以和任何自定義 Web 組件協同工作。

我們可以在同一元素、兄弟元素或任何子元素中引用模板引用變量。

這里是關於創建和使用模板引用變量的兩個例子:

<!-- phone 引用了 input 元素,併將 `value` 傳遞給事件句柄 --> <input #phone placeholder="phone number"> <button (click)="callPhone(phone.value)">Call</button> <!-- fax 引用了 input 元素,併將 `value` 傳遞給事件句柄 --> <input ref-fax placeholder="fax number"> <button (click)="callFax(fax.value)">Fax</button>

"phone" 的 (#) 前綴意味著我們將要定義一個 phone 變量。

相關文章

https://gf-rd.gitbooks.io/angular-2-step-by-step/content/chapters/2.3.html

北斗有巢氏 有巢氏北斗