Architecture > Pipes

Références

L'actualité

Librairie

L'information

Les pipes

Chaque application démarre avec ce qui semble être une tâche simple: obtenir des données, les transformer et les montrer aux utilisateurs. Obtenir des données peut être aussi simple que créer une variable locale ou aussi complexe que de transmettre des données en continu sur WebSocket.

Une fois que les données sont arrivées, vous pouvez afficher leurs valeurs brutes directement dans la vue, mais cela rend rarement une bonne expérience utilisateur. Par exemple, dans la plupart des cas d'utilisation, les utilisateurs préfèrent voir une date dans un format simple comme 15 avril 1988 plutôt que le format de chaîne brute Vendredi 15 avril 1988 00:00:00 GMT-0700 (heure avancée du Pacifique).

Les pipes Angular, un moyen d'écrire des transformations de valeur d'affichage que vous pouvez déclarer dans votre code HTML.

Utilisation des pipes

Un pipe prend des données en entrée et les transforme en une sortie souhaitée. Dans cette page, vous utiliserez des pipes pour transformer la propriété anniversaire d'un composant en une date conviviale.

Concentrez-vous sur le modèle du composant.

Dans l'expression d'interpolation, vous transmettez la valeur birthday du composant via l'opérateur de pipe ( | ) à la fonction Date du pipe sur la droite. Tous les pipes fonctionnent de cette façon.

Pipes intégré

Angular est livré avec un stock de pipes tels que DatePipe, UpperCasePipe, LowerCasePipe, CurrencyPipe et PercentPipe. Ils sont tous disponibles pour une utilisation dans n'importe quel modèle.

Paramétrer un pipes

Un pipe peut accepter un nombre quelconque de paramètres facultatifs pour affiner sa sortie. Pour ajouter des paramètres à un pipe, suivez le nom du pipe avec un signe deux-points ( : ), puis la valeur du paramètre (telle que la currency : 'EUR'). Si le canal accepte plusieurs paramètres, séparez les valeurs par des deux points (1:5)

Modifiez le modèle de date d'anniversaire pour attribuer un paramètre de format au pipe de dates. Après avoir formaté le 15 avril de son anniversaire, le héros apparaît en 04/15/88 :

La valeur du paramètre peut être toute expression de modèle valide, telle qu'un littéral de chaîne ou une propriété de composant. En d'autres termes, vous pouvez contrôler le format via une liaison de la même manière que vous contrôlez la valeur de l'anniversaire via une liaison.

Ecrivez un second composant qui lie le paramètre de format du pipe à la propriété format du composant. Voici le modèle pour ce composant :

Vous avez également ajouté un bouton au modèle et lié son événement click à la méthode toggleFormat() du composant. Cette méthode bascule la propriété format du composant entre une forme courte (shortDate) et une forme plus longue (fullDate).

Lorsque vous cliquez sur le bouton, la date affichée alterne entre "04/15/1988" et "Vendredi 15 avril 1988".



Chaînage de pipes

Vous pouvez chaîner des pipes dans des combinaisons potentiellement utiles. Dans l'exemple suivant, pour afficher l'anniversaire en majuscule, l'anniversaire est chaîné au DatePipe et au UpperCasePipe. L'anniversaire s'affiche comme ceci : 15 AVRIL 1988.

Cet exemple affiche VENDREDI 15 AVRIL 1988.

Pipes personnalisés

Vous pouvez écrire vos propres pipes personnalisées. Voici un pipe personnalisé nommé ExponentialStrengthPipe qui peut augmenter les pouvoirs d'un héros :

Cette définition de pipe révèle les points clés suivants :

  • Une pipe est une classe décorée avec des métadonnées de pipe.
  • La classe pipe implémente la méthode de l'interface transform PipeTransform qui accepte une valeur d'entrée suivie de paramètres facultatifs et renvoie la valeur transformée.
  • Il y aura un argument supplémentaire à la méthode transform pour chaque paramètre transmis au canal.
  • Pour indiquer à Angular qu'il s'agit d'un pipe, appliquez le décorateur @Pipe que vous importez à partir de la bibliothèque Angular principale.
  • Le décorateur @Pipe vous permet de définir le nom du pipe que vous utiliserez dans les expressions de modèle. Il doit s'agir d'un identifiant JavaScript valide. Le nom de votre pipe est exponentialStrength.

L'interface PipeTransform

Vous avez maintenant besoin d'un composant pour démontrer le pipe.


Notez les points suivants :
  • Vous utilisez votre pipe personnalisé de la même manière que vous utilisez les pipes intégrés.
  • Vous devez inclure votre pipe dans la declarations des AppModule.
Vous devez enregistrer des pipes personnalisées. Si vous ne le faites pas, Angular signale une erreur. Le générateur de la CLI Angular enregistre automatiquement le tuyau.

Calculateur de puissance

Ce n'est pas très amusant de mettre à jour le modèle pour tester le canal personnalisé. Mettez à niveau l'exemple en un "Calculateur de renforcement de la puissance" qui associe votre canal et la liaison de données bidirectionnelle à ngModel.



Détection des pipes et des modifications

Angular recherche les modifications apportées aux valeurs liées aux données via un processus de détection des modifications qui s'exécute après chaque événement DOM : chaque frappe au clavier, chaque déplacement de souris, chaque tick et tout le temps, et la réponse du serveur. Cela pourrait être cher. Angular s'efforce de réduire les coûts chaque fois que cela est possible et approprié.

Angular choisit un algorithme de détection de changement plus simple et plus rapide lorsque vous utilisez un canal. Dans l'exemple suivant, le composant utilise la stratégie de détection de changement par défaut pour surveiller et mettre à jour l'affichage de chaque héros. Voici le modèle :
La classe de composants compagnon fournit des héros, ajoute des héros dans le tableau et peut réinitialiser le tableau.

Vous pouvez ajouter des héros et Angular met à jour l'affichage lorsque vous le faites. Si vous cliquez sur le bouton reset, Angular remplace heroes par un nouveau tableau des héros originaux et met à jour l'affichage. Si vous ajoutez la possibilité de supprimer ou de modifier un héros, Angular détectera ces modifications et mettra également à jour l'affichage.

FlyingHeroesPipe

Ajouter un pipe FlyingHeroesPipe au répéteur *ngFor qui filtre la liste des héros uniquement aux héros qui peuvent voler.

Voici l'implémentation FlyingHeroesPipe, qui suit le modèle de canaux personnalisés décrit précédemment.

Bien que vous n'ayez pas le comportement que vous souhaitez, Angular n'est pas cassé. Il utilise simplement un algorithme de détection de changement différent qui ignore les modifications apportées à la liste ou à l'un de ses éléments.

Remarquez comment un héros est ajouté:

Vous ajoutez le héros dans le tableau heroes. La référence au tableau n'a pas changé. C'est le même tableau. C'est tout ce dont Angular se soucie. De son point de vue, même tableau, pas de changement, pas de mise à jour de l'affichage.

Pour résoudre ce problème, créez un tableau avec le nouveau héros ajouté et affectez-le à heroes. Cette fois, Angular détecte que la référence à la matrice a changé. Il exécute le pipe et met à jour l'affichage avec le nouveau tableau, qui inclut le nouveau héros volant.

Si vous modifiez le tableau, aucun canal n'est appelé et l'affichage n'est pas mis à jour. Si vous remplacez le tableau, le pipe s'exécute et l'affichage est mis à jour. L'application Flying Heroes étend le code avec des commutateurs de cases à cocher et des écrans supplémentaires pour vous aider à ressentir ces effets.


Le remplacement de la matrice est un moyen efficace de signaler à Angular de mettre à jour l'affichage. Quand remplacez-vous le tableau ? Lorsque les données changent. C'est une règle facile à suivre dans cet exemple où le seul moyen de modifier les données consiste à ajouter un héros.

Le plus souvent, vous ne savez pas quand les données ont changé, en particulier dans les applications qui changent de données de nombreuses façons, peut-être même dans des emplacements d'application très éloignés. Un composant d'une telle application ne peut généralement pas connaître ces modifications. De plus, il est déconseillé de déformer la conception des composants pour accueillir un pipe. Efforcez-vous de garder la classe de composant indépendante du code HTML. Le composant doit ignorer les tuyaux.

Pipes pures et impures

Il existe deux catégories de pipes: pure et impur. Les pipes sont pures par défaut. Vous créez un pipe impur en définissant sa valeur pur à false. Vous pouvez faire le Pipe FlyingHeroes impur comme ceci :

Avant de faire cela, comprenez la différence entre pur et impur, en commençant par un pipe pur.

Pipes pur

Angular exécute un pipe pur uniquement lorsqu'il détecte un changement pur de la valeur d'entrée. Un changement pur est soit un changement à une valeur d'entrée primitive (String, Number, Boolean, Symbol) ou une référence d'objet modifié (Date, Array, Function, Object).

Angular ignore les modifications apportées aux objets (composites). Cela n'appellera pas un canal pur si vous modifiez un mois d'entrée, ajoutez-le à un tableau d'entrée ou mettez à jour une propriété d'objet d'entrée.

Cela peut sembler restrictif, mais c'est aussi rapide. Une vérification de référence d'objet est rapide (beaucoup plus rapide qu'une vérification approfondie des différences). Ainsi, Angular peut rapidement déterminer s'il peut ignorer l'exécution du canal et la mise à jour d'une vue.

Pour cette raison, un pipe pur est préférable lorsque vous pouvez vivre avec la stratégie de détection de changement. Lorsque vous ne pouvez pas, vous pouvez utiliser le pipe impur. Ou vous pourriez ne pas utiliser de pipe du tout. Il peut être préférable de poursuivre l'objectif du pipe avec une propriété du composant, un point qui sera discuté plus tard dans cette page.

Pipes impur

Angular exécute un pipe impur pendant chaque cycle de détection de changement de composant. Un tuyau impur s'appelle souvent, aussi souvent que chaque frappe ou déplacement de souris. Avec cette préoccupation en tête, installez un pipe impur avec le plus grand soin. Un pipe long et coûteux pourrait détruire l'expérience utilisateur.

Pipe impur FlyingHeroesPipe

Une simple pression sur le commutateur transforme le FlyingHeroesPipe en FlyingHeroesImpurePipe. L'implémentation complète est la suivante :

FlyingHeroesImpurePipe

FlyingHeroesPipe

Vous héritez de FlyingHeroesPipe pour prouver le fait que rien n'a changé en interne. La seule différence est la déclaration pure dans les métadonnées du pipe.

C'est un bon candidat pour un pipe impur, car sa fonction transform est simple et rapide.

Vous pouvez obtenir un FlyingHeroesImpureComponent à partir de FlyingHeroesComponent.

Pipe impur AsyncPipe

AsyncPipe est un exemple intéressant de pipe impur. L'AsyncPipe accepte un Promise ou un Observable en tant qu'entrée et s'abonne automatiquement à l'entrée, pour finalement renvoyer les valeurs émises.

Le AsyncPipe est aussi stateful. Le canal maintient un abonnement à l'entrée Observable et continue à fournir des valeurs à Observable mesure qu'elles arrivent.

Cet exemple suivant lie une chaîne Observablede message (message$) à une vue avec le pipe async.

Le pipe Async enregistre le standard dans le code du composant. Le composant n'a pas besoin de s'abonner à la source de données asynchrone, d'extraire les valeurs résolues et de les exposer pour la liaison, et de se désabonner lorsqu'il est détruit (une source puissante de fuites de mémoire).


Pipe impur de mise en cache

Ecrivez un autre pipe impur, qui envoie une requête HTTP. Rappelez-vous que les pipes impurs sont appelés toutes les quelques millisecondes. Dans le code suivant, le pipe n'appelle le serveur que lorsque l'URL demandée change et met en cache la réponse du serveur. Le code utilise le client http Angular pour récupérer des données :

Maintenant, montrez-le dans un composant dont le modèle définit deux liaisons à ce canal, demandant toutes les deux aux héros du fichier heroes.json.
Le composant se présente comme suit :


Un point d'arrêt sur la demande de données du canal indique ce qui suit:
  • Chaque liaison obtient sa propre instance de canal.
  • Chaque instance de canal met en cache sa propre URL et ses propres données.
  • Chaque instance de canal appelle le serveur une seule fois.


JsonPipe

Dans l'exemple de code précédent, la deuxième liaison de pipe d'extraction illustre davantage de chaînage de pipe. Il affiche les mêmes données au format JSON en s'enchaînant avec le JsonPipe intégrées .

Le JsonPipe offre un moyen simple de diagnostiquer une laison de données qui échoue mystérieusement ou d'inspecter un objet pour une laison future.

Pipe pur et fonction pur

Un pipe pur utilise des fonction pur. Les fonctions pures traitent les entrées et renvoient les valeurs sans effets secondaires détectables. Avec la même entrée, ils devraient toujours retourner la même sortie.

Les pipes décrits plus haut dans cette page sont implémentés avec des fonctions pures. L'intégré DatePipe est un pipe pur avec une implémentation de fonction pure. Ainsi le sont les pipes ExponentialStrengthPipe et FlyingHeroesPipe. Précédemment, vous avez examiné le FlyingHeroesImpurePipe, un pipe impur avec une fonction pur.

Prochaines étapes

Les pipes constituent un excellent moyen d'encapsuler et de partager des transformations de valeur d'affichage courantes. Utilisez-les comme des styles, en les déposant dans les expressions de votre modèle pour enrichir l'attrait et la convivialité de vos vues. Explorez l'inventaire Angular des pipes intégrés dans la référence API. Essayez d'écrire un pipe personnalisé .

Pas de FilterPipe ni de OrderByPipe

Angular ne fournit pas de pipes pour filtrer ou trier les listes. Les développeurs familiarisés avec AngularJS les connaissent sous la forme filter et orderBy. Il n'y a pas d'équivalent avec Angular.

Angular n'offre pas de tels pipes car ils fonctionnent mal, filter et orderBy requièrent des paramètres qui font référence à des propriétés d'objet. Vous avez appris que de tels pipes doivent être impur et que Angular appelle des pipes impur dans presque chaque cycle de détection de changement.

Filtrer et surtout trier sont des opérations coûteuses. L'expérience utilisateur peut se dégrader gravement même pour des listes de taille moyenne lorsque Angular appelle ces méthodes de pipe plusieurs fois par seconde.

Imaginez un pipe de tri appliqué à une liste. La liste peut être triée par name et planet par propriétés d'origine de la manière suivante :

L'équipe Angular et de nombreux développeurs Angular expérimentés recommandent vivement de déplacer la logique de filtrage et de tri dans le composant lui-même. Le composant peut exposer une propriété filtered ou sorted et prendre le contrôle du moment et de la fréquence d'exécution de la logique de prise en charge. Toutes les fonctionnalités que vous auriez mises dans un canal et partagées dans l'application peuvent être écrites dans un service de filtrage / tri et injectées dans le composant.