Angular2 Pipe


AngularJs 1.x 中使用filters來幫助我們轉換templates中的輸出,但在Angular2中使用的是pipes,以下展示Angular 1.x and Angular 2中filter和pipe的對比:

Filter/Pipe Name Angular 1.x Angular 2
currency
date
uppercase
json
limitTo
lowercase
number  
orderBy  
filter  
async  
decimal  
percent  

Basic Pipes

// app.ts

// <reference path="typings/angular2/angular2.d.ts" />

import {Component, View, bootstrap} from 'angular2/angular2';

@Component({
  selector: 'pipes'
})
@View({
  templateUrl: 'pipesTemplate.html'
})
// Component controller
class PipesAppComponent {
  date: Date;

  constructor() {
    this.date = new Date();
  }
}

bootstrap(PipesAppComponent);
<!-- pipesTemplate.html -->
  <h1>Dates</h1>
  <!-- Sep 1, 2015 -->
  <p>{{date | date:'mediumDate'}}</p>
  <!-- September 1, 2015 -->
  <p>{{date | date:'yMMMMd'}}</p>
  <!-- 3:50 pm -->
  <p>{{date | date:'shortTime'}}</p>

結果:

 

New Pipes

decimal和percent是Angular2中新增的管道,參數規則是:{minIntegerDigits}.{minFractionDigits}-{maxFractionDigits}.

decimal管道在模板中使用number關鍵字

// app.ts

...

@View({
  templateUrl: 'pipesTemplate.html'
})

class PipesAppComponent {
  grade: number;
  rating: number;

  constructor() {
    this.grade = 0.99;
    this.rating = 9.1243;
  }
}

...

html

<h1>Decimals/Percentages</h1>
  <!-- 99.00% -->
  <p>{{grade | percent:'.2'}}</p>
  <!-- 09.12 -->
  <p>{{rating | number:'2.1-2'}}</p>

結果:

Async Pipe

Angular 2's async allows us to bind our templates directly to values that arrive asynchronously. This ability is great for working with promises and observables.

// app.ts

...

@Component({
  selector: 'pipes',
  changeDetection: 'ON_PUSH'
})
@View({
  templateUrl: 'pipesTemplate.html',
})

class PipesAppComponent {
  promise: Promise;

  constructor() {
    this.promise = new Promise(function(resolve, reject) {
      setTimeout(function() {
        resolve("Hey, I'm from a promise.");
      }, 2000)
    });
  }
}

...

html

<!-- pipesTemplate.html -->
  <h1>Async</h1>
  <p>{{ promise | async}}</p>

After a 2 second delay, the value from the resolved promise will be displayed on the screen.

Custom Pipes

自定義pipe需要使用@Pipe裝飾器,並實現PipeTransform接口里的transform方法。定義好的pipe要在需使用pipe的view或component中聲明。

Pipe接口的定義

export interface Pipe {
  name: string;
  pure?: boolean;
}

PipeDecorator

export const Pipe: PipeDecorator = <PipeDecorator>makeDecorator('Pipe', {
  name: undefined,
  pure: true, // 默認是pure
});

PipeTransform接口

export interface PipeTransform {
  transform(value: any, ...args: any[]): any;
}

管道分類

  • pure 管道:僅當管道輸入值變化的時候,才執行轉換操作,默認的類型是 pure 類型。(備注:輸入值變化是指原始數據類型如:string、number、boolean 等的數值或對象的引用值發生變化)

  • impure 管道:在每次變化檢測期間都會執行,如鼠標點擊或移動都會執行 impure 管道

// app.ts

import {Component, View, bootstrap, Pipe, PipeTransform} from 'angular2/angular2';

...

// We use the @Pipe decorator to register the name of the pipe
@Pipe({
  name: 'tempConvert'
})
// The work of the pipe is handled in the tranform method with our pipe's class
class TempConvertPipe implements PipeTransform {
  transform(value: number, args: any[]) {
    if(value && !isNaN(value) && args[0] === 'celsius') {
      var temp = (value - 32) * 5/9;
      var places = args[1];
      return temp.toFixed(places) + ' C';       
    }

    return;
  }
}

...

@View({
  templateUrl: 'pipesTemplate.html',

  // We can pass the pipe class name into the pipes key to make it usable in our views
  pipes: [TempConvertPipe]
})

class PipesAppComponent {
  temperature: number;

  constructor() {
    this.temperature = 85;
  }
}

html

<h1>Custom Pipes - Convert Temperature</h1>
  <!-- 85 F -->
  <h3>Fahrenheit: {{temperature + ' F'}}</h3>
  <!-- 29.4 C -->
  <h3>Celsius: {{temperature | tempConvert:'celsius':1}}</h3>

結果

過濾出指定范圍的值

定義一個pipe

import {Pipe, PipeTransform} from 'angular2/core';

// Tell Angular2 we're creating a Pipe with TypeScript decorators
@Pipe({
  name: 'AgePipe'
})
export class AgePipe implements PipeTransform {

  // Transform is the new "return function(value, args)" in Angular 1.x
  transform(value, args?) {
    // ES6 array destructuring
    let [minAge, maxAge] = args;
    return input.filter(person => {
      return person.age >= +minAge && person.age <= +maxAge;
    });
  }

}
import {Component} from 'angular2/core';  
import {AgePipe} from './pipes/age-pipe/age-pipe';


@Component({
  selector: 'playground-app',
  templateUrl: 'app/playground.html',
  // tell our component it uses our AgePipe
  pipes: [AgePipe]
})
export class PlaygroundApp {  
  sliderValue:number = 20;
anotherSliderValue: number = 90;

  people:Array<any> = [{
      name: 'Justin Bieber',
      age: 21
    }, {
      name: 'Miley Cyrus',
      age: 23
    }, {
      name: 'John Legend',
      age: 37
    }, {
      name: 'Betty White',
      age: 94
    }, {
      name: 'Roger Waters',
      age: 72
    }, {
      name: 'Larry Page',
      age: 42
    }];
}

html

<div>  
  <p>
  0
    <input type="range" min="0" max="100" 
          [value]="sliderValue" 
          (input)="sliderValue = $event.target.value" />
  100
  </p>
  <span>{{ sliderValue }}</span>
<p>
  0
    <input type="range" min="0" max="100" 
          [(ngModel)]="anotherSliderValue" />
  100
  </p>
  <span>{{anotherSliderValue }}</span>
    <ul>
      <li *ngFor="#person of people | AgePipe:sliderValue:anotherSliderValue">
        {{ person.name }} ({{ person.age }})
      </li>
    </ul>
</div>  

 


免責聲明!

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



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