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');
  }));
});


Modified text is an extract of the original Stack Overflow Documentation
Sous licence CC BY-SA 3.0
Non affilié à Stack Overflow