Angular 2
Pipes
Recherche…
Introduction
Le tuyau |
character est utilisé pour appliquer des canaux dans Angular 2. Les tubes sont très similaires aux filtres d'AngularJS car ils permettent de transformer les données dans un format spécifié.
Paramètres
Fonction / Paramètre | Explication |
---|---|
@Pipe ({name, pure}) | les métadonnées pour la conduite, doivent immédiatement précéder la classe de conduite |
nom: chaîne | ce que vous utiliserez à l'intérieur du modèle |
pur: booléen | la valeur par défaut est true, cochez cette case pour que votre tube soit réévalué plus souvent |
transformer (valeur, args []?) | la fonction appelée pour transformer les valeurs du modèle |
valeur: tout | la valeur que vous souhaitez transformer |
args: any [] | les arguments dont vous avez besoin inclus dans votre transformation. Marquer des arguments facultatifs avec le? opérateur comme si transform (value, arg1, arg2?) |
Remarques
Cette rubrique couvre Angular2 Pipes , un mécanisme de transformation et de mise en forme des données dans les modèles HTML dans une application Angular2.
Chaining Pipes
Les tuyaux peuvent être enchaînés.
<p>Today is {{ today | date:'fullDate' | uppercase}}.</p>
Tuyaux personnalisés
my.pipe.ts
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({name: 'myPipe'})
export class MyPipe implements PipeTransform {
transform(value:any, args?: any):string {
let transformedValue = value; // implement your transformation logic here
return transformedValue;
}
}
my.component.ts
import { Component } from '@angular/core';
@Component({
selector: 'my-component',
template: `{{ value | myPipe }}`
})
export class MyComponent {
public value:any;
}
my.module.ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { MyComponent } from './my.component';
import { MyPipe } from './my.pipe';
@NgModule({
imports: [
BrowserModule,
],
declarations: [
MyComponent,
MyPipe
],
})
export class MyModule { }
Tuyaux Intégrés
Angular2 est livré avec quelques tuyaux intégrés:
Tuyau | Usage | Exemple |
---|---|---|
DatePipe | date | {{ dateObj | date }} // output is 'Jun 15, 2015' |
UpperCasePipe | uppercase | {{ value | uppercase }} // output is 'SOMETEXT' |
LowerCasePipe | lowercase | {{ value | lowercase }} // output is 'sometext' |
CurrencyPipe | currency | {{ 31.00 | currency:'USD':true }} // output is '$31' |
PercentPipe | percent | {{ 0.03 | percent }} //output is %3 |
Il y en a d'autres Regardez ici pour leur documentation.
Exemple
hotel-reservation.component.ts
import { Component } from '@angular/core';
@Component({
moduleId: module.id,
selector: 'hotel-reservation',
templateUrl: './hotel-reservation.template.html'
})
export class HotelReservationComponent {
public fName: string = 'Joe';
public lName: string = 'SCHMO';
public reservationMade: string = '2016-06-22T07:18-08:00'
public reservationFor: string = '2025-11-14';
public cost: number = 99.99;
}
hotel-reservation.template.html
<div>
<h1>Welcome back {{fName | uppercase}} {{lName | lowercase}}</h1>
<p>
On {reservationMade | date} at {reservationMade | date:'shortTime'} you
reserved room 205 for {reservationDate | date} for a total cost of
{cost | currency}.
</p>
</div>
Sortie
Welcome back JOE schmo
On Jun 26, 2016 at 7:18 you reserved room 205 for Nov 14, 2025 for a total cost of
$99.99.
Déboguer avec JsonPipe
JsonPipe peut être utilisé pour déboguer l’état de tout interne donné.
Code
@Component({
selector: 'json-example',
template: `<div>
<p>Without JSON pipe:</p>
<pre>{{object}}</pre>
<p>With JSON pipe:</p>
<pre>{{object | json}}</pre>
</div>`
})
export class JsonPipeExample {
object: Object = {foo: 'bar', baz: 'qux', nested: {xyz: 3, numbers: [1, 2, 3, 4, 5]}};
}
Sortie
Without JSON Pipe:
object
With JSON pipe:
{object:{foo: 'bar', baz: 'qux', nested: {xyz: 3, numbers: [1, 2, 3, 4, 5]}}
Pipe personnalisée disponible à l'échelle mondiale
Pour rendre une application personnalisée disponible au niveau de l'application, lors du démarrage de l'application, étendez PLATFORM_PIPES.
import { bootstrap } from '@angular/platform-browser-dynamic';
import { provide, PLATFORM_PIPES } from '@angular/core';
import { AppComponent } from './app.component';
import { MyPipe } from './my.pipe'; // your custom pipe
bootstrap(AppComponent, [
provide(PLATFORM_PIPES, {
useValue: [
MyPipe
],
multi: true
})
]);
Tutoriel ici: https://scotch.io/tutorials/create-a-globally-available-custom-pipe-in-angular-2
Créer un tuyau personnalisé
app / pipes.pipe.ts
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({name: 'truthy'})
export class Truthy implements PipeTransform {
transform(value: any, truthy: string, falsey: string): any {
if (typeof value === 'boolean'){return value ? truthy : falsey;}
else return value
}
}
app / my-component.component.ts
import { Truthy} from './pipes.pipe';
@Component({
selector: 'my-component',
template: `
<p>{{value | truthy:'enabled':'disabled' }}</p>
`,
pipes: [Truthy]
})
export class MyComponent{ }
Déballez les valeurs asynchrones avec un tuyau asynchrone
import { Component } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/observable/of';
@Component({
selector: 'async-stuff',
template: `
<h1>Hello, {{ name | async }}</h1>
Your Friends are:
<ul>
<li *ngFor="let friend of friends | async">
{{friend}}
</li>
</ul>
`
})
class AsyncStuffComponent {
name = Promise.resolve('Misko');
friends = Observable.of(['Igor']);
}
Devient:
<h1>Hello, Misko</h1>
Your Friends are:
<ul>
<li>
Igor
</li>
</ul>
Extension d'un tuyau existant
import { Pipe, PipeTransform } from '@angular/core';
import { DatePipe } from '@angular/common'
@Pipe({name: 'ifDate'})
export class IfDate implements PipeTransform {
private datePipe: DatePipe = new DatePipe();
transform(value: any, pattern?:string) : any {
if (typeof value === 'number') {return value}
try {
return this.datePipe.transform(value, pattern)
} catch(err) {
return value
}
}
}
Pipes Stateful
Angular 2 propose deux types de tuyaux différents - sans état et avec état. Les tuyaux sont sans état par défaut. Cependant, nous pouvons implémenter des canaux avec état en définissant la propriété pure
sur false
. Comme vous pouvez le voir dans la section des paramètres, vous pouvez spécifier un name
et déclarer si le tube doit être pur ou non, c'est-à-dire avec état ou sans état. Alors que les données transitent par un canal sans état (qui est une fonction pure) qui ne se souvient de rien, les données peuvent être gérées et mémorisées par des canaux avec état. AsyncPipe
fourni par Angular 2 est un bon exemple de pipe avec état.
Important
Notez que la plupart des tuyaux doivent tomber dans la catégorie des tuyaux sans état. C'est important pour des raisons de performance, car Angular peut optimiser les tuyaux sans état pour le détecteur de changement. Donc, utilisez les tuyaux avec état avec précaution. En général, l’optimisation des tubes dans Angular 2 améliore considérablement les performances par rapport aux filtres dans Angular 1.x. Dans Angular 1, le cycle de digestion devait toujours réexécuter tous les filtres, même si les données n'avaient pas du tout changé. Dans Angular 2, une fois que la valeur d'un tube a été calculée, le détecteur de changement ne sait plus exécuter ce canal, à moins que l'entrée ne change.
Mise en place d'un tuyau à états
import {Pipe, PipeTransform, OnDestroy} from '@angular/core';
@Pipe({
name: 'countdown',
pure: false
})
export class CountdownPipe implements PipeTransform, OnDestroy {
private interval: any;
private remainingTime: number;
transform(value: number, interval: number = 1000): number {
if (!parseInt(value, 10)) {
return null;
}
if (typeof this.remainingTime !== 'number') {
this.remainingTime = parseInt(value, 10);
}
if (!this.interval) {
this.interval = setInterval(() => {
this.remainingTime--;
if (this.remainingTime <= 0) {
this.remainingTime = 0;
clearInterval(this.interval);
delete this.interval;
}
}, interval);
}
return this.remainingTime;
}
ngOnDestroy(): void {
if (this.interval) {
clearInterval(this.interval);
}
}
}
Vous pouvez ensuite utiliser le tuyau comme d'habitude:
{{ 1000 | countdown:50 }}
{{ 300 | countdown }}
Il est important que votre pipe implémente également l'interface OnDestroy
afin que vous puissiez nettoyer une fois votre pipe détruite. Dans l'exemple ci-dessus, il est nécessaire d'effacer l'intervalle pour éviter les fuites de mémoire.
Tuyau dynamique
Scénario d'utilisation: une vue de tableau se compose de différentes colonnes avec un format de données différent qui doit être transformé avec différents canaux.
table.component.ts
... import { DYNAMIC_PIPES } from '../pipes/dynamic.pipe.ts'; @Component({ ... pipes: [DYNAMIC_PIPES] }) export class TableComponent { ... // pipes to be used for each column table.pipes = [ null, null, null, 'humanizeDate', 'statusFromBoolean' ], table.header = [ 'id', 'title', 'url', 'created', 'status' ], table.rows = [ [ 1, 'Home', 'home', '2016-08-27T17:48:32', true ], [ 2, 'About Us', 'about', '2016-08-28T08:42:09', true ], [ 4, 'Contact Us', 'contact', '2016-08-28T13:28:18', false ], ... ] ... }
dynamic.pipe.ts
import { Pipe, PipeTransform } from '@angular/core'; // Library used to humanize a date in this example import * as moment from 'moment'; @Pipe({name: 'dynamic'}) export class DynamicPipe implements PipeTransform { transform(value:string, modifier:string) { if (!modifier) return value; // Evaluate pipe string return eval('this.' + modifier + '(\'' + value + '\')') } // Returns 'enabled' or 'disabled' based on input value statusFromBoolean(value:string):string { switch (value) { case 'true': case '1': return 'enabled'; default: return 'disabled'; } } // Returns a human friendly time format e.g: '14 minutes ago', 'yesterday' humanizeDate(value:string):string { // Humanize if date difference is within a week from now else returns 'December 20, 2016' format if (moment().diff(moment(value), 'days') < 8) return moment(value).fromNow(); return moment(value).format('MMMM Do YYYY'); } } export const DYNAMIC_PIPES = [DynamicPipe];
table.component.html
<table> <thead> <td *ngFor="let head of data.header">{{ head }}</td> </thead> <tr *ngFor="let row of table.rows; let i = index"> <td *ngFor="let column of row">{{ column | dynamic:table.pipes[i] }}</td> </tr> </table>
Résultat
| ID | Page Title | Page URL | Created | Status | --------------------------------------------------------------------- | 1 | Home | home | 4 minutes ago | Enabled | | 2 | About Us | about | Yesterday | Enabled | | 4 | Contact Us | contact | Yesterday | Disabled | ---------------------------------------------------------------------
Tester un tuyau
Étant donné un tuyau qui inverse une chaîne
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({ name: 'reverse' })
export class ReversePipe implements PipeTransform {
transform(value: string): string {
return value.split('').reverse().join('');
}
}
Il peut être testé en configurant le fichier de spécifications comme ceci
import { TestBed, inject } from '@angular/core/testing';
import { ReversePipe } from './reverse.pipe';
describe('ReversePipe', () => {
beforeEach(() => {
TestBed.configureTestingModule({
providers: [ReversePipe],
});
});
it('should be created', inject([ReversePipe], (reversePipe: ReversePipe) => {
expect(reversePipe).toBeTruthy();
}));
it('should reverse a string', inject([ReversePipe], (reversePipe: ReversePipe) => {
expect(reversePipe.transform('abc')).toEqual('cba');
}));
});