Angular 管道

2022-06-30 10:33 更新

用管道轉(zhuǎn)換數(shù)據(jù)

管道用來對字符串、貨幣金額、日期和其他顯示數(shù)據(jù)進(jìn)行轉(zhuǎn)換和格式化。管道是一些簡單的函數(shù),可以在模板表達(dá)式中用來接受輸入值并返回一個(gè)轉(zhuǎn)換后的值。例如,你可以使用一個(gè)管道把日期顯示為 1988 年 月 15 日,而不是其原始字符串格式。

本主題中使用的范例應(yīng)用,參閱現(xiàn)場演練 / 下載范例。

Angular 為典型的數(shù)據(jù)轉(zhuǎn)換提供了內(nèi)置的管道,包括國際化的轉(zhuǎn)換(i18n),它使用本地化信息來格式化數(shù)據(jù)。數(shù)據(jù)格式化常用的內(nèi)置管道如下:

  • ?DatePipe?:根據(jù)本地環(huán)境中的規(guī)則格式化日期值。
  • ?UpperCasePipe?:把文本全部轉(zhuǎn)換成大寫。
  • ?LowerCasePipe ?:把文本全部轉(zhuǎn)換成小寫。
  • ?CurrencyPipe ?:把數(shù)字轉(zhuǎn)換成貨幣字符串,根據(jù)本地環(huán)境中的規(guī)則進(jìn)行格式化。
  • ?DecimalPipe?:把數(shù)字轉(zhuǎn)換成帶小數(shù)點(diǎn)的字符串,根據(jù)本地環(huán)境中的規(guī)則進(jìn)行格式化。
  • ?PercentPipe ?:把數(shù)字轉(zhuǎn)換成百分比字符串,根據(jù)本地環(huán)境中的規(guī)則進(jìn)行格式化。

你還可以創(chuàng)建管道來封裝自定義轉(zhuǎn)換,并在模板表達(dá)式中使用自定義管道。

先決條件

要想使用管道,你應(yīng)該對這些內(nèi)容有基本的了解:

  • Typescript 和 HTML5 編程
  • 帶有 CSS 樣式的 HTML 模板
  • 組件

在模板中使用管道

要應(yīng)用管道,請如下所示在模板表達(dá)式中使用管道操作符(?|?),緊接著是該管道的名字,對于內(nèi)置的 ?DatePipe ?它的名字是 ?date ?。這個(gè)例子中的顯示如下:

  • ?app.component.html? 在另一個(gè)單獨(dú)的模板中使用 ?date ?來顯示生日。
  • ?hero-birthday1.component.ts? 使用相同的管道作為組件內(nèi)嵌模板的一部分,同時(shí)該組件也會設(shè)置生日值。

  • src/app/app.component.html
  • <p>The hero's birthday is {{ birthday | date }}</p>
  • src/app/hero-birthday1.component.ts
  • import { Component } from '@angular/core';
    
    @Component({
      selector: 'app-hero-birthday',
      template: "<p>The hero's birthday is {{ birthday | date }}</p>"
    })
    export class HeroBirthdayComponent {
      birthday = new Date(1988, 3, 15); // April 15, 1988 -- since month parameter is zero-based
    }

該組件的 ?birthday ?值通過管道操作符(?|?)流向 ?date ?函數(shù)。

使用參數(shù)和管道鏈來格式化數(shù)據(jù)

可以用可選參數(shù)微調(diào)管道的輸出。例如,你可以使用 ?CurrencyPipe ?和國家代碼(如 EUR)作為參數(shù)。模板表達(dá)式 ?{{ amount | currency:'EUR' }}? 會把 ?amount ?轉(zhuǎn)換成歐元。緊跟在管道名稱( ?currency ?)后面的是冒號(?:?)和參數(shù)值(?'EUR'?)。

如果管道能接受多個(gè)參數(shù),就用冒號分隔這些值。例如,?{{ amount | currency:'EUR':'Euros '}}? 會把第二個(gè)參數(shù)(字符串 ?'Euros '?)添加到輸出字符串中。你可以使用任何有效的模板表達(dá)式作為參數(shù),比如字符串字面量或組件的屬性。

有些管道需要至少一個(gè)參數(shù),并且允許使用更多的可選參數(shù),比如 ?SlicePipe ?。例如, ?{{ slice:1:5 }}? 會創(chuàng)建一個(gè)新數(shù)組或字符串,它以第 1 個(gè)元素開頭,并以第 5 個(gè)元素結(jié)尾。

范例:格式化日期

下面的例子顯示了兩種不同格式(?'shortDate'? 和 ?'fullDate'?)之間的切換:

  • 該 ?app.component.html? 模板使用 ?DatePipe ?(名為 ?date?)的格式參數(shù)把日期顯示為 04/15/88 。
  • ?hero-birthday2.component.ts? 組件把該管道的 format 參數(shù)綁定到 ?template ?中組件的 ?format ?屬性,并添加了一個(gè)按鈕,其 click 事件綁定到了該組件的 ?toggleFormat()? 方法。
  • ?hero-birthday2.component.ts? 組件的 ?toggleFormat() ?方法會在短格式(?'shortDate'?)和長格式(?'fullDate'?)之間切換該組件的 ?format ?屬性。

  • src/app/app.component.html
  • <p>The hero's birthday is {{ birthday | date:"MM/dd/yy" }} </p>
  • src/app/hero-birthday2.component.ts (template)
  • template: `
      <p>The hero's birthday is {{ birthday | date:format }}</p>
      <button (click)="toggleFormat()">Toggle Format</button>
    `
  • src/app/hero-birthday2.component.ts (class)
  • export class HeroBirthday2Component {
      birthday = new Date(1988, 3, 15); // April 15, 1988 -- since month parameter is zero-based
      toggle = true; // start with true == shortDate
    
      get format()   { return this.toggle ? 'shortDate' : 'fullDate'; }
      toggleFormat() { this.toggle = !this.toggle; }
    }

點(diǎn)擊 Toggle Format 按鈕可以在 04/15/1988 和 Friday, April 15, 1988 之間切換日期格式。

范例:通過串聯(lián)管道應(yīng)用兩種格式

可以對管道進(jìn)行串聯(lián),以便一個(gè)管道的輸出成為下一個(gè)管道的輸入。

在下面的范例中,串聯(lián)管道首先將格式應(yīng)用于一個(gè)日期值,然后將格式化之后的日期轉(zhuǎn)換為大寫字符。 ?src/app/app.component.html? 模板的第一個(gè)標(biāo)簽頁把 ?DatePipe ?和 ?UpperCasePipe ?的串聯(lián)起來,將其顯示為 APR 15, 1988。?src/app/app.component.html? 模板的第二個(gè)標(biāo)簽頁在串聯(lián) ?uppercase ?之前,還把 ?fullDate ?參數(shù)傳給了 ?date?,將其顯示為 FRIDAY, APRIL 15, 1988。

  • src/app/app.component.html (1)
  • The chained hero's birthday is
    {{ birthday | date | uppercase}}
  • src/app/app.component.html (2)
  • The chained hero's birthday is
    {{  birthday | date:'fullDate' | uppercase}}

為自定義數(shù)據(jù)轉(zhuǎn)換創(chuàng)建管道

創(chuàng)建自定義管道來封裝那些內(nèi)置管道沒有提供的轉(zhuǎn)換。然后就可以在模板表達(dá)式中使用自定義管道了,像內(nèi)置管道一樣,把輸入值轉(zhuǎn)換成顯示輸出。

把一個(gè)類標(biāo)記為一個(gè)管道

要把類標(biāo)記為管道并提供配置元數(shù)據(jù),請把 ?@Pipe? 裝飾器應(yīng)用到這個(gè)類上。管道類名是 ?UpperCamelCase?(類名的一般約定),相應(yīng)的 ?name ?字符串是 ?camelCase ?的。不要在 ?name ?中使用連字符。

在模板表達(dá)式中使用 ?name ?就像在內(nèi)置管道中一樣。

  • 把你的管道包含在 ?NgModule ?元數(shù)據(jù)的 ?declarations ?字段中,以便它能用于模板。請查看范例應(yīng)用中的 ?app.module.ts? 文件(現(xiàn)場演練 /  下載范例)。
  • 注冊自定義管道。?Angular CLI? 的 ?ng generate pipe? 命令會自動注冊該管道。

使用 PipeTransform 接口

在自定義管道類中實(shí)現(xiàn) ?PipeTransform ?接口來執(zhí)行轉(zhuǎn)換。

Angular 調(diào)用 ?transform ?方法,該方法使用綁定的值作為第一個(gè)參數(shù),把其它任何參數(shù)都以列表的形式作為第二個(gè)參數(shù),并返回轉(zhuǎn)換后的值。

范例:指數(shù)級轉(zhuǎn)換

在游戲中,可能希望實(shí)現(xiàn)一種指數(shù)級轉(zhuǎn)換,以指數(shù)級增加英雄的力量。例如,如果英雄的得分是 2,那么英雄的能量會指數(shù)級增長 10 次,最終得分為 1024。你可以使用自定義管道進(jìn)行這種轉(zhuǎn)換。

下列代碼范例顯示了兩個(gè)組件定義:

  • ?exponential-strength.pipe.ts? 通過一個(gè)執(zhí)行轉(zhuǎn)換的 ?transform ?方法定義了一個(gè)名為 ?exponentialStrength ?的自定義管道。它為傳給管道的參數(shù)定義了 ?transform ?方法的一個(gè)參數(shù)(?exponent?)。
  • ?power-booster.component.ts? 組件演示了如何使用該管道,指定了一個(gè)值( 2 )和一個(gè) exponent 參數(shù)( 10 )。

  • src/app/exponential-strength.pipe.ts
  • 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 = 1): number {
        return Math.pow(value, exponent);
      }
    }
  • src/app/power-booster.component.ts
  • import { Component } from '@angular/core';
    
    @Component({
      selector: 'app-power-booster',
      template: `
        <h2>Power Booster</h2>
        <p>Super power boost: {{2 | exponentialStrength: 10}}</p>
      `
    })
    export class PowerBoosterComponent { }

瀏覽器顯示如下:

Power Booster

Superpower boost: 1024

要檢查 ?exponentialStrength ?管道的行為,請查看現(xiàn)場演練 / 下載范例,并在模板中修改值和可選的指數(shù)參數(shù)。

通過管道中的數(shù)據(jù)綁定來檢測變更

你可以通過帶有管道的數(shù)據(jù)綁定來顯示值并響應(yīng)用戶操作。如果是原始類型的輸入值,比如 ?String ?或 ?Number ?,或者是對象引用型的輸入值,比如 ?Date ?或 ?Array ?,那么每當(dāng) Angular 檢測到輸入值或引用有變化時(shí),就會執(zhí)行該輸入管道。

比如,你可以修改前面的自定義管道范例,通過 ?ngModel ?的雙向綁定來輸入數(shù)量和提升因子,如下面的代碼范例所示。

import { Component } from '@angular/core';

@Component({
  selector: 'app-power-boost-calculator',
  template: `
    <h2>Power Boost Calculator</h2>
    <label for="power-input">Normal power: </label>
    <input id="power-input" type="text" [(ngModel)]="power">
    <label for="boost-input">Boost factor: </label>
    <input id="boost-input" type="text" [(ngModel)]="factor">
    <p>
      Super Hero Power: {{power | exponentialStrength: factor}}
    </p>
  `,
  styles: ['input {margin: .5rem 0;}']
})
export class PowerBoostCalculatorComponent {
  power = 5;
  factor = 1;
}

每當(dāng)用戶改變 “normal power” 值或 “boost factor” 時(shí),就會執(zhí)行 ?exponentialStrength ?管道。

Angular 會檢測每次變更,并立即運(yùn)行該管道。對于原始輸入值,這很好。但是,如果要在復(fù)合對象中更改某些內(nèi)部值(例如日期中的月份、數(shù)組中的元素或?qū)ο笾械膶傩裕托枰私庾兏鼨z測的工作原理,以及如何使用 ?impure?(非純)管道。

變更檢測的工作原理

Angular 會在每次 DOM 事件(每次按鍵、鼠標(biāo)移動、計(jì)時(shí)器滴答和服務(wù)器響應(yīng))之后運(yùn)行的變更檢測過程中查找對數(shù)據(jù)綁定值的更改。下面這段不使用管道的例子演示了 Angular 如何利用默認(rèn)的變更檢測策略來監(jiān)控和更新 ?heroes ?數(shù)組中每個(gè)英雄的顯示效果。范例顯示如下:

  • 在 ?flying-heroes.component.html (v1)? 模板中, ?*ngFor? 會重復(fù)顯示英雄的名字。
  • 與之相伴的組件類 ?flying-heroes.component.ts (v1)? 提供了一些英雄,把這些英雄添加到數(shù)組中,并重置了該數(shù)組。

  • src/app/flying-heroes.component.html (v1)
  • <label for="hero-name">New hero name: </label>
    <input type="text" #box
           id="hero-name"
           (keyup.enter)="addHero(box.value); box.value=''"
           placeholder="hero name">
    <button (click)="reset()">Reset list of heroes</button>
      <div *ngFor="let hero of heroes">
        {{hero.name}}
      </div>
  • src/app/flying-heroes.component.ts (v1)
  • export class FlyingHeroesComponent {
      heroes: any[] = [];
      canFly = true;
      constructor() { this.reset(); }
    
      addHero(name: string) {
        name = name.trim();
        if (!name) { return; }
        const hero = {name, canFly: this.canFly};
        this.heroes.push(hero);
      }
    
      reset() { this.heroes = HEROES.slice(); }
    }

每次用戶添加一個(gè)英雄時(shí),Angular 都會更新顯示內(nèi)容。如果用戶點(diǎn)擊了 Reset 按鈕,Angular 就會用原來這些英雄組成的新數(shù)組來替換 ?heroes ?,并更新顯示。如果你添加刪除或更改了某個(gè)英雄的能力,Angular 也會檢測這些變化并更新顯示。

然而,如果對于每次更改都執(zhí)行一個(gè)管道來更新顯示,就會降低你應(yīng)用的性能。因此,Angular 會使用更快的變更檢測算法來執(zhí)行管道,如下一節(jié)所述。

檢測原始類型和對象引用的純變更

通過默認(rèn)情況下,管道會定義成純的(pure),這樣 Angular 只有在檢測到輸入值發(fā)生了純變更時(shí)才會執(zhí)行該管道。純變更是對原始輸入值(比如 ?String?、?Number?、?Boolean ?或 ?Symbol ?)的變更,或是對對象引用的變更(比如 ?Date?、?Array?、?Function?、?Object?)。

純管道必須使用純函數(shù),它能處理輸入并返回沒有副作用的值。換句話說,給定相同的輸入,純函數(shù)應(yīng)該總是返回相同的輸出。

使用純管道,Angular 會忽略復(fù)合對象中的變化,例如往現(xiàn)有數(shù)組中新增的元素,因?yàn)闄z查原始值或?qū)ο笠帽葘ο笾械牟町愡M(jìn)行深度檢查要快得多。Angular 可以快速判斷是否可以跳過執(zhí)行該管道并更新視圖。

但是,以數(shù)組作為輸入的純管道可能無法正常工作。為了演示這個(gè)問題,修改前面的例子來把英雄列表過濾成那些會飛的英雄。在 ?*ngFor? 中使用 ?FlyingHeroesPipe ?,代碼如下。這個(gè)例子的顯示如下:

  • 帶有新管道的模板(?flying-heroes.component.html (flyers)?)。
  • ?FlyingHeroesPipe ?自定義管道實(shí)現(xiàn)(?flying-heroes.pipe.ts?)。

  • src/app/flying-heroes.component.html (flyers)
  • <div *ngFor="let hero of (heroes | flyingHeroes)">
      {{hero.name}}
    </div>
  • src/app/flying-heroes.pipe.ts
  • import { Pipe, PipeTransform } from '@angular/core';
    
    import { Hero } from './heroes';
    
    @Pipe({ name: 'flyingHeroes' })
    export class FlyingHeroesPipe implements PipeTransform {
      transform(allHeroes: Hero[]) {
        return allHeroes.filter(hero => hero.canFly);
      }
    }

該應(yīng)用現(xiàn)在展示了意想不到的行為:當(dāng)用戶添加了會飛的英雄時(shí),它們都不會出現(xiàn)在 “Heroes who fly” 中。發(fā)生這種情況是因?yàn)樘砑佑⑿鄣拇a會把它 push 到 ?heroes ?數(shù)組中:

this.heroes.push(hero);

而變更檢測器會忽略對數(shù)組元素的更改,所以管道不會運(yùn)行。

Angular 忽略了被改變的數(shù)組元素的原因是對數(shù)組的引用沒有改變。由于 Angular 認(rèn)為該數(shù)組仍是相同的,所以不會更新其顯示。

獲得所需行為的方法之一是更改對象引用本身??梢杂靡粋€(gè)包含新更改過的元素的新數(shù)組替換該數(shù)組,然后把這個(gè)新數(shù)組作為輸入傳給管道。在上面的例子中,你可以創(chuàng)建一個(gè)附加了新英雄的數(shù)組,并把它賦值給 ?heroes?。 Angular 檢測到了這個(gè)數(shù)組引用的變化,并執(zhí)行了該管道。

總結(jié)一下,如果修改了輸入數(shù)組,純管道就不會執(zhí)行。如果替換了輸入數(shù)組,就會執(zhí)行該管道并更新顯示。

上述例子演示了如何更改組件的代碼來適應(yīng)某個(gè)管道。

為了讓你的組件更簡單,獨(dú)立于那些使用管道的 HTML,你可以用一個(gè)不純的管道來檢測復(fù)合對象(如數(shù)組)中的變化,如下一節(jié)所述。

檢測復(fù)合對象中的非純變更

要在復(fù)合對象內(nèi)部進(jìn)行更改后執(zhí)行自定義管道(例如更改數(shù)組元素),就需要把管道定義為 ?impure ?以檢測非純的變更。每當(dāng)按鍵或鼠標(biāo)移動時(shí),Angular 都會檢測到一次變更,從而執(zhí)行一個(gè)非純管道。

雖然非純管道很實(shí)用,但要小心使用。長時(shí)間運(yùn)行非純管道可能會大大降低你的應(yīng)用速度。

通過把 ?pure ?標(biāo)志設(shè)置為 ?false ?來把管道設(shè)置成非純的:

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

下面的代碼顯示了 ?FlyingHeroesImpurePipe ?的完整實(shí)現(xiàn),它擴(kuò)展了 ?FlyingHeroesPipe ?以繼承其特性。這個(gè)例子表明你不需要修改其他任何東西 - 唯一的區(qū)別就是在管道元數(shù)據(jù)中把 ?pure ?標(biāo)志設(shè)置為 ?false ?。

  • src/app/flying-heroes.pipe.ts (FlyingHeroesImpurePipe)
  • @Pipe({
      name: 'flyingHeroesImpure',
      pure: false
    })
    export class FlyingHeroesImpurePipe extends FlyingHeroesPipe {}
  • src/app/flying-heroes.pipe.ts (FlyingHeroesPipe)
  • import { Pipe, PipeTransform } from '@angular/core';
    
    import { Hero } from './heroes';
    
    @Pipe({ name: 'flyingHeroes' })
    export class FlyingHeroesPipe implements PipeTransform {
      transform(allHeroes: Hero[]) {
        return allHeroes.filter(hero => hero.canFly);
      }
    }

對于非純管道,?FlyingHeroesImpurePipe ?是個(gè)不錯(cuò)的選擇,因?yàn)樗?nbsp;?transform ?函數(shù)非常簡單快捷:

return allHeroes.filter(hero => hero.canFly);

你可以從 ?FlyingHeroesComponent ?派生一個(gè) ?FlyingHeroesImpureComponent?。如下面的代碼所示,只有模板中的管道發(fā)生了變化。

<div *ngFor="let hero of (heroes | flyingHeroesImpure)">
  {{hero.name}}
</div>

要想確認(rèn)是否在用戶添加英雄時(shí)更新了顯示,請參閱現(xiàn)場演練 / 下載范例。

從一個(gè)可觀察對象中解包數(shù)據(jù)

可觀察對象能讓你在應(yīng)用的各個(gè)部分之間傳遞消息。建議在事件處理、異步編程以及處理多個(gè)值時(shí)使用這些可觀察對象??捎^察對象可以提供任意類型的單個(gè)或多個(gè)值,可以是同步的(作為一個(gè)函數(shù)為它的調(diào)用者提供一個(gè)值),也可以是異步的。

使用內(nèi)置的 ?AsyncPipe ?接受一個(gè)可觀察對象作為輸入,并自動訂閱輸入。如果沒有這個(gè)管道,你的組件代碼就必須訂閱這個(gè)可觀察對象來使用它的值,提取已解析的值、把它們公開進(jìn)行綁定,并在銷毀這段可觀察對象時(shí)取消訂閱,以防止內(nèi)存泄漏。 ?AsyncPipe ?是一個(gè)非純管道,可以節(jié)省組件中的樣板代碼,以維護(hù)訂閱,并在數(shù)據(jù)到達(dá)時(shí)持續(xù)從該可觀察對象中提供值。

下列代碼范例使用 ?async ?管道將帶有消息字符串( ?message$? )的可觀察對象綁定到視圖中。

import { Component } from '@angular/core';

import { Observable, interval } from 'rxjs';
import { map, take } from 'rxjs/operators';

@Component({
  selector: 'app-hero-async-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.message$ = this.getResendObservable();
  }

  resend() {
    this.message$ = this.getResendObservable();
  }

  private getResendObservable() {
    return interval(500).pipe(
      map(i => this.messages[i]),
      take(this.messages.length)
    );
  }
}

緩存 HTTP 請求

為了使用 HTTP 與后端服務(wù)進(jìn)行通信,?HttpClient ?服務(wù)使用了可觀察對象,并提供了 ?HttpClient.get()? 方法來從服務(wù)器獲取數(shù)據(jù)。這個(gè)異步方法會發(fā)送一個(gè) HTTP 請求,并返回一個(gè)可觀察對象,它會發(fā)出請求到的響應(yīng)數(shù)據(jù)。

如 ?AsyncPipe ?所示,你可以使用非純管道 ?AsyncPipe ?接受一個(gè)可觀察對象作為輸入,并自動訂閱輸入。你也可以創(chuàng)建一個(gè)非純管道來建立和緩存 HTTP 請求。

每當(dāng)組件運(yùn)行變更檢測時(shí)就會調(diào)用非純管道,這可能每隔幾毫秒就運(yùn)行一次。為避免出現(xiàn)性能問題,只有當(dāng)請求的 URL 發(fā)生變化時(shí)才會調(diào)用該服務(wù)器(如下例所示),并使用該管道緩存服務(wù)器的響應(yīng)。顯示如下:

  • ?fetch ?管道( ?fetch-json.pipe.ts? )。
  • 一個(gè)用于演示該請求的挽具組件(?hero-list.component.ts?),它使用一個(gè)模板,該模板定義了兩個(gè)到該管道的綁定,該管道會向 ?heroes.json? 文件請求英雄數(shù)組。第二個(gè)綁定把 ?fetch ?管道與內(nèi)置的 ?JsonPipe ?串聯(lián)起來,以 JSON 格式顯示同一份英雄數(shù)據(jù)。

  • src/app/fetch-json.pipe.ts
  • import { HttpClient } from '@angular/common/http';
    import { Pipe, PipeTransform } from '@angular/core';
    
    @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;
      }
    }
  • src/app/hero-list.component.ts
  • import { Component } from '@angular/core';
    
    @Component({
      selector: 'app-hero-list',
      template: `
        <h2>Heroes from JSON File</h2>
    
        <div *ngFor="let hero of ('assets/heroes.json' | fetch) ">
          {{hero.name}}
        </div>
    
        <p>Heroes as JSON:
          {{'assets/heroes.json' | fetch | json}}
        </p>`
    })
    export class HeroListComponent { }

在上面的例子中,管道請求數(shù)據(jù)時(shí)的剖面展示了如下幾點(diǎn):

  • 每個(gè)綁定都有自己的管道實(shí)例。
  • 每個(gè)管道實(shí)例都會緩存自己的 URL 和數(shù)據(jù),并且只調(diào)用一次服務(wù)器。

?fetch ?和 ?fetch-json? 管道會像這樣在瀏覽器中顯示英雄:

Heroes from JSON File

Windstorm
Bombasto
Magneto
Tornado

Heroes as JSON: [ { "name": "Windstorm", "canFly": true }, { "name": "Bombasto", "canFly": false }, { "name": "Magneto", "canFly": false }, { "name": "Tornado", "canFly": true } ]

內(nèi)置的 ?JsonPipe ?提供了一種方法來診斷一個(gè)離奇失敗的數(shù)據(jù)綁定,或用來檢查一個(gè)對象是否能用于將來的綁定。

管道的優(yōu)先級

管道操作符要比三目運(yùn)算符(??:?)的優(yōu)先級高,這意味著 ?a ? b : c | x? 會被解析成 ?a ? b : (c | x)?。

由于這種優(yōu)先級設(shè)定,如果你要用管道處理三目元算符的結(jié)果,就要把整個(gè)表達(dá)式包裹在括號中,比如 ?(a ? b : c) | x?。

<!-- use parentheses in the third operand so the pipe applies to the whole expression -->
{{ (true ? 'true' : 'false') | uppercase }}


以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號