Angular4.0基礎知識之組件
Angular4.0基礎知識之路由
Angular4.0依賴注入
Angular4.0數據綁定&管道
數據綁定
數據綁定允許你將組件控制器的屬性和方法與組件的模板連接起來,大大降低了開發時的編碼量。
常見的表現形式有:
- 插值表達式:
<h1>{{title}}</h1>
,即把屬性|表達式插入到HTML標簽中 - 屬性綁定:
<img [src]="imgUrl" />
,也就是將屬性|表達式綁定到HTML標簽的屬性上 - 事件綁定:
<button (click)="show()"></button>
,講組件控制器的一個方法綁定到模板元素的事件上
在Angular中,默認的數據綁定是單向的(AngularJS1.0中全部是雙向綁定,這也是性能差的原因之一),所謂的雙向綁定,也就是控制器的屬性反映到模板中,同時,模板中顯示出的屬性被修改之后,對應的控制器屬性同時發生變化;單向綁定取出了模板=>控制器的方向,使性能大大提升。(當然,雙向綁定並不是被去掉了,你也可以手動指定使用雙向綁定,雙向綁定現在變成了一個可選項,而不是框架的默認行為)
事件綁定
<button (click)="doOnClick($event)"></button>
doOnClick(event:any){
console.log(event);
}
如上代碼是一個經典的事件綁定例子,被綁定的事件可以是一個標准事件也可以是一個自定義事件,綁定的操作可以是控制器里的一個方法,也可以只一個賦值表達式等等。
屬性綁定
如下例子所示
// 使用屬性綁定
<img [src]="imgUrl" />
// 使用插值表達式
<img src="{{imgUrl}}" />
又是一個經典的例子,不難理解,上面兩個方法實現的效果是完全一致的,事實上,這兩個方法沒有優劣之分,你只需要按照自己的喜好去選擇即可
HTML屬性綁定
- 基本HTMl屬性綁定
<td [attr.colspan]="value"></td>
- class綁定
<div class="aaa bbb" [class]="val"></div> // 這種情況會覆蓋原先的class
<div [class.aaa]="booleanVal"></div> // 通過一個Boolean值開關來控制是否啟用某一個class名,適合管理單一class名
<div [ngClass]="{aaa:isA,bbb:isB}"></div> // 通過對象的形式開控制多個class的開關,適合同時管理多個className
- 樣式綁定
和class綁定類似,只不過綁定的對象為style屬性
<button [style.color]="isRed?'red':'green'">Red</button>
<div [ngStyle]="{color:red,'font-style':bool?'italic':'normal'}"></div>
雙向綁定
雙向綁定即視圖和模型保持同步,無論視圖和模型哪一方改變,另一方都一起同步改變。
前面所學到的事件綁定是從視圖到模型,把模板中元素的事件綁定到控制器中的方法;屬性綁定的方向是從控制器到模板,使用方括號講組件控制器的屬性綁定到模板。
<input [value]="name" (input)="doOnInput($event)" />
export class BindComponent implements OnInit {
name: string;
doOnInput(event){
this.name=event.target.value;
}
}
這樣就實現了一個雙向綁定,當input內容變化的時候,出發事件,修改模型中的屬性值,當模型中的屬性值改變的時候,優惠在視圖中表現出來。
當然,Angular肯定提供了內置的雙向綁定支持:
<input [(ngModel)]="name" />
由於[(ngModel)]
用在input元素上,默認綁定的是input
事件。雙向綁定最常用的用途就是表單處理。
當然,雙向綁定本來就應該用於input系列元素上,因為這些元素允許你去修改這些值,並顯示出來。
將會在表單處理章節更詳細講。
管道
舉個例子,例如我要在頁面上顯示我的生日信息,假設現在從服務器獲取到的日期是一個Date對象,那么把它直接輸出到頁面上肯定是用戶體驗很不好的(一大串亂七八糟的字符串)。管道就是用來處理數據的,從原始值到你所需要的值,這一個過程。
使用實例:
<p>{{birthday | date | uppercase}}</p>
上面例子中我們就使用了兩個內置的管道,第一個是獲取到Date對象的日期信息,第二個是把小寫字母轉換成大寫。
內置管道
常用的管道:
- uppercase 大寫
- lowercase 小寫
date日期管道
日期管道符可以接受參數,用來規定輸出日期的格式。
<p>現在的時間是{{today | date:'yyyy-MM-dd HH:mm:ss'}}</p>
number 數字處理管道
接收的參數格式為{最少整數位數}.{最少小數位數}-{最多小數位數}
其中最少整數位數默認為1
最少小數位數默認為0
最多小數位數默認為3
當小數位數少於規定的{最少小數位數}時,會自動補0
當小數位數多於規定的{最多小數位數}時,會四舍五入
自定義管道
- 生成管道:
ng g pipe pipe/multiple
,此處用來做Demo的管道作用是扒一個數放大n倍,也就是乘法……
生成的管道代碼:
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({
name: 'multiple'
})
export class MultiplePipe implements PipeTransform {
transform(value: any, args?: any): any {
return null;
}
}
可以看出,管道是一個實現了PipeTransform並且帶有@Pipe裝飾器的類,用於把源數據根據參數和方法定義處理成想要的結果。
但是,當你打開
app.modules.ts
的時候,你會發現在declaration數組里多出來了一個MultiplePipe的聲明,也就是說,管道也是需要聲明的,只是命令行工具自動添加進去了。
其中value是管道前端的原始值,args是一個可選參數,也就是管道的參數,最終管道把處理結果返回出去即可。
如下,我們很輕易地創建了一個管道:
import {Pipe, PipeTransform} from '@angular/core';
@Pipe({
name: 'multiple'
})
export class MultiplePipe implements PipeTransform {
transform(value: number, args?: number): number {
if (!args) {
args = 1;
}
return value * args;
}
}
在實戰項目中,我們對管道有了新的用法,根據傳入的參數來過濾商品列表:
import {Pipe, PipeTransform} from '@angular/core';
import {Product} from '../shared/product.service';
@Pipe({
name: 'productFilter'
})
export class ProductFilterPipe implements PipeTransform {
transform(productList: Product[], filterField: string, keyword: string): any {
if (!filterField || !keyword) {
return productList;
}
return productList.filter((product: Product) => product[filterField].indexOf(keyword) >= 0);
}
}