Angular2 - 管道

管道的做用:api

  管道把數據做爲輸入,而後轉換它,給出指望的輸出能夠有好的將「顯示--值」轉換器 聲明在HTML中。數組

管道表達式:  {{ 顯示 | 格式 }}緩存

使用管道:服務器

<p>The hero's birthday is {{ birthday | date }}</p>

內置的管道:app

  好比 DatePipeUpperCasePipeLowerCasePipeCurrencyPipe 和 PercentPipe。 它們全均可以直接用在任何模板中async

對管道進行參數化:ide

  管道可能接受任何數量的可選參數來對它的輸出進行微調。 能夠在管道名後面添加一個冒號( : )再跟一個參數值,來爲管道添加參數(好比 currency:'EUR')。 若是這個管道能夠接受多個參數,那麼就用冒號來分隔這些參數值(好比 slice:1:5)。工具

<p>The hero's birthday is {{ birthday | date:"MM/dd/yy" }} </p>

 

  還能夠將管道的格式參數綁定到該組件的屬性上:以下所示fetch

template: `
  <p>The hero's birthday is {{ birthday | date:format }}</p>
  <button (click)="toggleFormat()">Toggle Format</button>
`
export class HeroBirthday2Component {
  birthday = new Date(1988, 3, 15); // April 15, 1988
  toggle = true; // start with true == shortDate
 get format()   { return this.toggle ? 'shortDate' : 'fullDate'; }
  toggleFormat() { this.toggle = !this.toggle; }
}

鏈式管道:把管道串聯在一塊兒,以組合出一些潛在的有用功能。ui

 

The chained hero's birthday is
{{ birthday | date | uppercase}}

//一樣的方式連接了這兩個管道,並且同時還給 date 管道傳進去一個參數
The chained hero's birthday is
{{  birthday | date:'fullDate' | uppercase}}

 

自定義管道:

 

 

import { Pipe, PipeTransform } from '@angular/core';
/*
 * Raise the value exponentially
 * Takes an exponent argument that defaults to 1.
 * Usage:
 *   value | exponentialStrength:exponent
 * Example:
 *   {{ 2 | exponentialStrength:10 }}
 *   formats to: 1024
*/
@Pipe({name: 'exponentialStrength'})
export class ExponentialStrengthPipe implements PipeTransform {
  transform(value: number, exponent: string): number {
    let exp = parseFloat(exponent);
    return Math.pow(value, isNaN(exp) ? 1 : exp);
  }
}

 

在這個管道的定義中體現了幾個關鍵點:

  • 管道是一個帶有「管道元數據(pipe metadata)」裝飾器的類。

  • 這個管道類實現了 PipeTransform 接口的 transform 方法,該方法接受一個輸入值和一些可選參數,並返回轉換後的值。

  • 當每一個輸入值被傳給 transform 方法時,還會帶上另外一個參數,好比你這個管道就有一個 exponent(放大指數) 參數。

  • 能夠經過 @Pipe 裝飾器來告訴 Angular:這是一個管道。該裝飾器是從 Angular 的 core 庫中引入的。

  • 這個 @Pipe 裝飾器容許你定義管道的名字,這個名字會被用在模板表達式中。它必須是一個有效的 JavaScript 標識符。 好比,你這個管道的名字是 exponentialStrength

PipeTransform 接口
transform 方法是管道的基本要素。 PipeTransform接口中定義了它,並用它指導各類工具和編譯器。 
理論上說,它是可選的。Angular 不會管它,而是直接查找並執行 transform 方法。

請注意如下幾點:

  • 你使用自定義管道的方式和內置管道徹底相同。

  • 你必須在 AppModule 的 declarations 數組中包含這個管道

 

 

 

 

純(pure)管道與非純(impure)管道

  有兩類管道:純的與非純的。 默認狀況下,管道都是純的。之前見到的每一個管道都是純的。 經過把它的 pure 標誌設置爲 false,你能夠製做一個非純管道。你能夠像這樣讓 FlyingHeroesPipe 變成非純的:

@Pipe({
  name: 'flyingHeroesImpure',
  pure: false
})

純管道:

  Angular 只有在它檢測到輸入值發生了純變動時纔會執行純管道。 純變動是指對原始類型值(StringNumberBooleanSymbol)的更改, 或者對對象引用(DateArrayFunctionObject)的更改。

非純管道

  Angular 會在每一個組件的變動檢測週期中執行非純管道。 非純管道可能會被調用不少次,和每一個按鍵或每次鼠標移動同樣頻繁。

 

非純 AsyncPipe

     AsyncPipe 接受一個 Promise 或 Observable 做爲輸入,而且自動訂閱這個輸入,最終返回它們給出的值。

  AsyncPipe 管道是有狀態的。 該管道維護着一個所輸入的 Observable 的訂閱,而且持續從那個 Observable 中發出新到的值。

  下面例子使用該 async 管道把一個消息字符串(message$)的 Observable 綁定到視圖中:

import { Component } from '@angular/core';
 
import { Observable, interval } from 'rxjs';
import { map, take } from 'rxjs/operators';
 
@Component({
  selector: 'app-hero-message',
  template: `
    <h2>Async Hero Message and AsyncPipe</h2>
    <p>Message: {{ message$ | async }}</p>
    <button (click)="resend()">Resend</button>`,
})
export class HeroAsyncMessageComponent {
  message$: Observable<string>;
 
  private messages = [
    'You are my hero!',
    'You are the best hero!',
    'Will you be my hero?'
  ];
 
  constructor() { this.resend(); }
 
  resend() {
    this.message$ = interval(500).pipe(
      map(i => this.messages[i]),
      take(this.messages.length)
    );
  }
}

一個非純並且帶緩存的管道

  來寫更多的非純管道:一個向服務器發起 HTTP 請求的管道。

  時刻記住,非純管道可能每隔幾微秒就會被調用一次。 若是你不當心點,這個管道就會發起一大堆請求「攻擊」服務器。

  下面這個管道只有當所請求的 URL 發生變化時纔會向服務器發起請求。它會緩存服務器的響應。 代碼以下,它使用Angular http客戶端來接收數據。

import { Pipe, PipeTransform } from '@angular/core';
import { HttpClient }          from '@angular/common/http';
@Pipe({
  name: 'fetch',
  pure: false
})
export class FetchJsonPipe  implements PipeTransform {
  private cachedData: any = null;
  private cachedUrl = '';
 
  constructor(private http: HttpClient) { }
 
  transform(url: string): any {
    if (url !== this.cachedUrl) {
      this.cachedData = null;
      this.cachedUrl = url;
      this.http.get(url).subscribe( result => this.cachedData = result );
    }
 
    return this.cachedData;
  }
}
相關文章
相關標籤/搜索