Angular4.0從入門到實戰打造在線競拍網站學習筆記之四--數據綁定&管道


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屬性綁定

  1. 基本HTMl屬性綁定
<td [attr.colspan]="value"></td>
  1. 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
  1. 樣式綁定

和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
當小數位數多於規定的{最多小數位數}時,會四舍五入

自定義管道

  1. 生成管道: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);
  }

}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM