Le Guide Angular | Marmicode
  • Le Guide Angular par Marmicode
  • Pourquoi Angular ?
  • ECMAScript 6+
    • Un Peu d'Histoire
    • Propriétés du Langage
    • "Single-Threaded" donc Asynchrone
    • Event Loop
    • Classes
    • Hoisting is Dead: var vs. let vs. const
    • this & "binding"
    • Arrow Functions
    • Template Strings
    • Syntactic Sugar
      • Spread
      • Destructuring
      • Rest
      • Object Literal Property Value Shorthand
    • Named Parameters
    • Compatibilité
  • TypeScript
    • Pourquoi TypeScript ?
    • De l'ECMAScript au TypeScript
    • Visibilité des Propriétés
    • Typing des Propriétés
    • Types
    • Interfaces
    • Inference
    • Duck Typing
    • Duck Typing Patterns
      • Compatibilité de Librairies
      • Entity Constructor
    • Décorateurs
      • Décorateurs de Propriété
      • Décorateurs de Classe
      • Décorateurs de Méthode & Paramètres
    • Quelques Liens
  • Tools
    • Clavier mécanique
    • Git
    • Command Line
    • NodeJS
    • NPM
    • Yarn
      • Pourquoi Yarn ?
      • Définition et Installation des Dépendances
      • Scripts
      • Mise à Jour et Automatisation
    • Chrome
    • IntelliJ / WebStorm / VSCode
      • Raccourcis clavier IntelliJ / WebStorm
    • Floobits
    • Angular CLI
    • StackBlitz
    • Compodoc
  • Angular
    • Bootstrap
    • Composants
      • Root Component
      • Template Interpolation
      • Property Binding
      • Class & Style Binding
      • Event Binding
      • *ngIf
      • *ngFor
      • L'approche MVC
      • Création de Composants
      • Exemple
    • Container vs. Presentational Components
    • Interaction entre Composants
      • Input
      • Output
      • Exemple
    • Change Detection
      • Les Approches Possibles
      • Fonctionnement de la Change Detection
      • Optimisation de la Change Detection
      • Immutabilité
      • Quelques Liens
    • Project Structure & Modules
      • Entry Point
      • Définition d'un Module
      • Root Module
      • Feature Module
      • Shared Module
      • Exemple
    • Dependency Injection
      • Qu'est-ce que la "Dependency Injection" ?
      • Injection d'un Service Angular
      • Services & Providers
      • Portée des Services
      • Tree-Shakable Services
      • Class vs Injection Token
      • Exemple
    • Callback Hell vs. Promise vs. Async / Await
      • Callback Hell
      • Promise
      • Async / Await
    • Observables
      • Reactive Programming
      • Promise vs Observable
      • Subscribe
      • Unsubscribe ⚠️
      • Création d'un Observable
      • Opérateurs
        • Définition d'un Opérateur
        • Lettable Operators vs Legacy Methods
        • map
        • filter
        • mergeMap & switchMap
        • shareReplay
        • buffer
        • debounceTime
        • distinctUntilChanged
        • retry
      • Quelques Liens
      • Talks
    • Http
      • Pourquoi HttpClient ?
      • Utilisation de HttpClient
      • Utilisation dans un Service
      • Gestion de la Subscription ⚠️
    • State Management
      • Quelques Liens
      • Talks
    • GraphQL
    • Formulaires
      • Template-driven Forms 🤢
      • Reactive Forms 👍
        • Avantages des "Reactive Forms"
        • La boite à outils des "Reactive Forms"
        • Validation
        • Observation des Changements
    • Directives
      • Attribute Directive
      • Structural Directive
    • Pipes
    • Routing
      • Mise en Place du Routing
      • Lazy Loading
      • Project Structure
      • Route Guards
    • Testing
      • Unit-Testing
        • 📺Introduction au Test-Driven Development
        • Jasmine
        • Unit-Test Synchrone
        • Test-Driven Development
        • Unit-Test Asynchrone
        • TestBed
        • Unit-Test d'un Service
        • Unit-Test d'un Composant
        • Unit-Test et Spies
        • Unit-Test et HttpClient
      • End-to-End
      • Talks
    • Sécurité
      • Quelques Liens
    • Animation
    • Internationalisation
    • Quelques Liens
  • Cookbook
    • Authentification et Autorisation
    • Remplacement Dynamique de Composants
    • Lazy Loading without Router
    • Project Structure
    • SCAM Modules
    • Setup a Mock ReSTful API
  • Autres Ressources
  • Stay Tuned
    • 🎁-20% sur nos workshops avec le code GUIDEANGULAR
    • 🐦Suivez-moi !
    • 📺Cours Vidéo
    • 📬Newsletter
    • 📝Blog
  • Nos Services
    • Formation Angular
    • Atelier Unit-Testing Angular
    • Atelier Architecture Angular
    • Consultation à Distance & Code Review
  • Nos Guides
    • Guide Agile
    • Guide API ReST
    • Guide NodeJS
Propulsé par GitBook
Sur cette page
  • Utilisation des Pipes
  • Syntaxe
  • Paramètres
  • Chaînage
  • Les Pipes natifs
  • Le Pipe async
  • Pipes personnalisés
  • "Dependency Injection"
  • Pureté du Pipe
  • Les Pipes purs
  • Les Pipes impurs
  1. Angular

Pipes

PrécédentStructural DirectiveSuivantRouting

Dernière mise à jour il y a 5 ans

Les Pipes sont des filtres utilisables directement depuis la vue afin de transformer les valeurs lors du "binding".

Utilisation des Pipes

Syntaxe

La syntaxe des Pipes est simplement inspirée des Pipes des shell UNIX que l'on retrouve dans de nombreux systèmes de templating.

<div>{{ user.firstName | lowercase }}</div>

Paramètres

Les Pipes peuvent prendre des paramètres qu'il faut mettre après le Pipe et séparés avec le symbole ":".

<div>{{ user.firstName | slice:0:10 }}</div>

Chaînage

Les "pipes" peuvent être chaînés.

<div>{{ user.firstName | slice:0:10 | lowercase }}</div>

Les Pipes natifs

Angular dispose de plusieurs "pipes" natifs : .

Le Pipe async

Le Pipe async est un Pipe capable de consommer des Observables (ou Promise) en appelant implicitement la méthode subscribe (ou then) afin de "binder" les valeurs contenus dans l'Observable (ou la Promise).

Pipes personnalisés

Pour créer un Pipe personnalisé, il faut :

  1. implémenter une classe suivant l'interface PipeTransform,

  2. décorer cette classe avec le décorateur @Pipe() en indiquant le nom du Pipe.

  3. ajouter la classe aux declarations (et exports) du module associé.

Le Pipe price ci-dessous permet d'afficher le prix d'un produit représenté avec la classe Price suivante :

export class Price {

    coefficient?: number;
    exponent?: number;
    currency?: string;

    constructor(args: Price = {}) {
        this.coefficient = args.coefficient;
        this.exponent = args.exponent;
        this.currency = args.currency;
    }

}
@Pipe({
    name: 'price'
})
export class PricePipe implements PipeTransform {

    transform(price: Price): string {

        if (price == null) {
            return null;
        }

        const amount = price.coefficient * Math.pow(10, price.exponent);

        return `${amount} ${price.currency}`;

    }

}
@NgModule({
    declarations: [
        PricePipe
    ],
    exports: [
        PricePipe
    ]
})
export class PriceModule {
}

Le Pipe peut alors être utilisé dans n'importe quel composant contenu dans un module qui importe le module PriceModule :

export class BookPreviewComponent {
    bookPrice = new Price({
        coefficient: 1010,
        exponent: -2,
        currency: 'USD'
    });
}
<div>{{ bookPrice | price }}</div>

On obtient alors le résultat suivant :

<div>10.1 USD</div>

"Dependency Injection"

Le constructeur d'un Pipe peut être utiliser pour injecter des dépendances.

Dans notre cas, nous souhaitons injecter le Pipe currency afin de profiter de ses fonctionnalités tout en simplifiant son utilisation.

@Pipe({
    name: 'price'
})
export class PricePipe implements PipeTransform {

    constructor(private _currencyPipe: CurrencyPipe) {
    }

    transform(price: Price): string {

        if (price == null) {
            return null;
        }

        const amount = price.coefficient * Math.pow(10, price.exponent);

        return this._currencyPipe.transform(amount, price.currency);

    }

}

Malheureusement, Angular ne définit pas nativement de providers pour les Pipes.

/* @HACK: Cf. https://github.com/angular/angular/issues/15107 */
@NgModule({
    providers: [
        CurrencyPipe
    ]
})
export class InjetableCurrencyPipeModule {
}

@NgModule({
    imports: [
        InjetableCurrencyPipeModule
    ]
})
export class BookModule {
}

Pureté du Pipe

Les Pipes purs

Par défaut, les Pipes sont purs. C'est à dire que leur méthode transform est une fonction pure, la valeur retournée ne dépend que des paramètres reçus et les appels n'ont aucun effet de bord. Autrement dit, le Pipe est "stateless".

Angular ne considère que les paramètres ont changé que si leurs références ont changé.

Les Pipes impurs

@Pipe({
    pure: false
})
export class BadPipe {
}

Nativement, seuls les Pipes suivant sont impurs :

  • async : Il est impur car les valeurs retournées par ce Pipe peuvent changer à n'importe quel moment étant donné qu'elles proviennent d'une source asynchrone (Observable ou Promise).

  • json : Etant donné qu'il est principalement utilisé pour le "debug", ce Pipe est impur car il est préférable que la valeur retournée soit mise à jour même si l'immutabilité n'est pas respectée.

  • slice : Bien que ce Pipe fonctionnerait parfaitement en étant pur, il est probablement impur pour faciliter l'adoption d'Angular par la communauté car malheureusement l'immutabilité des Arrays est rarement respectée par les développeurs Angular.

Ne les utilisez pas !

L'implémentation de Pipes impurs est un "code smell" qui révèle généralement des problèmes de conception.

Dans les cas des Observables, ce Pipe unsubscribe automatiquement à la destruction de la vue. Cf. .

En attendant la résolution de ce bug , une des solutions de contournement pour injecter un Pipe est de l'ajouter à la liste des providers d'un module importé par le module définissant notre Pipe.

Par optimisation, à chaque , Angular n'évalue les Pipes purs (i.e. appel de la méthode transform) que quand les paramètres changent.

Il faut donc veiller au respect de l'.

Les Pipes impurs sont évalués à chaque même quand les paramètres ne changent pas. Ils sont déclarés en passant la valeur false au paramètre pure du décorateur Pipe :

https://angular.io/api?type=pipe
Gestion de la Subscription
https://github.com/angular/angular/issues/15107
Change Detection
immutabilité
Change Detection