L'actualité

Angular 🚦 Signaux 📡 (L’avenir d’Angular)

Angular 🚦 Signaux 📡 (L'avenir d'Angular)

Pourquoi et comment utiliser les signaux angulaires

J’ai mis à jour cet article après la sortie d’Angular v16.0.0-next.7

Avant de commencer avec Angular Signals 🚦, vous êtes-vous déjà demandé comment les modifications apportées à votre modèle se reflétaient dans la vue ?

Si vous savez comment Angular détecte les changements et met à jour les vues, vous pouvez passer à la section suivante sur les signaux ! 💨

Lorsque vous apportez des mises à jour à votre modèle, Angular applique automatiquement ces modifications à la vue correspondante. Cela permet une interaction transparente et synchronisée entre le modèle et la vue, permettant une expérience utilisateur fluide.

Croyez-moi, ce n’est pas par magie ! 🧙‍♂️✨

La clé de cette synchronisation est Change Detection et Zone js .

Bien que CD et Zone js ne soient pas au centre de cet article, nous allons brièvement explorer comment Angular utilise ces outils pour synchroniser la vue avec les modèles.

Les applications angulaires sont construites à l’aide d’une architecture basée sur des composants, où chaque composant représente une caractéristique ou une fonctionnalité spécifique. L’application angulaire est un arbre de composants.

En utilisant des zones et en exécutant du code à l’intérieur de celles-ci, le framework peut obtenir une meilleure visibilité sur les opérations en cours d’exécution. Cela lui permet de gérer plus efficacement les erreurs et, surtout, de déclencher la détection des changements chaque fois que quelque chose se passe dans l’application (opération asynchrone, événement DOM …)

  • 1 : Zone.js détecte quand quelque chose se passe dans l’application.
  • 2 : Zone.js déclenche la détection de changement pour mettre à jour l’état de l’application.

Lorsque la détection de changement démarre 🔥, le framework parcourt tous les composants de l’arborescence pour vérifier si leur état a changé ou non et si le nouvel état affecte la vue. Si tel est le cas, la partie DOM du composant qui est affectée par la modification est mise à jour.

Cette fonctionnalité a un impact significatif sur les performances de l’application, elle effectue des travaux qui peuvent ne pas être nécessaires, puisque la majorité des composants peuvent ne pas être affectés par l’événement.

Nous pouvons optimiser les performances de l’application en modifiant la stratégie de détection des changements dans le composant à l’aide de la stratégie OnPush . Cependant, cette approche nécessite une attention particulière.

Mais pourquoi expliquez-vous cela ? Cet article concerne les signaux angulaires, n’est-ce pas ? 😕

Oui, car Angular Signals peut nous aider à éviter ces vérifications inutiles😊 et à ne mettre à jour que la partie de l’application qui a changé.

Alors maintenant, nous allons en apprendre davantage sur les signaux angulaires 🥳🥳🥳. Allons-y 🏃‍♀️ 🏃 🏃‍♀️ 🏃

Angulaire 🚦 Signaux 📡

Que sont les signaux angulaires 🤔 ?

Les signaux sont une valeur réactive, techniquement une fonction sans argument [( () => T)] , lorsque nous l’exécutons, ils renvoient la valeur. Nous pouvons dire que le signal est un type particulier de valeur qui peut être observé 🧐 pour les changements.

Comment crée-t-on un signal ?

Nous créons et initialisons un signal en appelant la fonctionsignal()

// Signature de la fonction signal 
export function signal<T>( initialValue : T, options?: CreateSignalOptions <T>): WritableSignal <T>

//Signature de l'interface
d'export CreateSignalOptions CreateSignalOptions <T> { /** * Une fonction de comparaison qui définit l'égalité des valeurs de signal. */ égal ? : ValueEqualityFn <T> ; } //Comment l'utiliser const movies = signal< Movie []>([]);






La signalfonction est une fonction TypeScript qui crée un S ignal . Il prend deux arguments :

  • initialValue: Représente la valeur initiale du signal , et il peut être de n’importe quel typeT
  • optionsest un objet du CreateSignalOptionstype qui inclut une equalméthode pour comparer deux valeurs de type T. Si l’ optionsobjet n’est pas fourni lors de la création d’un signal, la defaultEqualsfonction sera utilisée à la place. La defaultEqualsfonction compare deux valeurs du même type Ten utilisant une combinaison de l’ ===opérateur et de la Object.isméthode

La signalfonction renvoie un WritableSignal<T>.Signal est une fonction getter, mais le type donne la possibilité de modifier la valeur par trois méthodes :WritableSignal

  • set set(value: T): void ] for replacement ( réglez le signal sur une nouvelle valeur et informez les personnes à charge )
  • updateupdate(updateFn: (value: T) => T) ] pour dériver une nouvelle valeur ( mettre à jour la valeur du signal en fonction de sa valeur actuelle et notifier les personnes à charge ), l’ opération de mise à jour utilise l’ opération set() pour effectuer mises à jour dans les coulisses.
  • mutatemutate(mutatorFn: (value: T) => void) ] pour effectuer une mutation interne de la valeur actuelle ( mettre à jour la valeur actuelle en la mutant sur place et notifier toutes les personnes à charge )

Signal est donc une valeur réactive qui peut être observée, mise à jour et notifiée à toute personne à charge.

Mais qu’est-ce que cela signifie d’avertir les personnes à charge😕 ?

C’est la partie magique 🪄 de Signal . Nous allons maintenant voir quelles sont les personnes à charge pour les signaux et comment les notifier .

Signal n’est pas seulement une valeur qui peut être modifiée, c’est plus que cela, Signal est une valeur réactive 🔃 et est un producteur qui avertit les consommateurs (personnes à charge) lorsqu’il change.

Ainsi, les personnes à charge dans Signal sont tout code qui a enregistré un intérêt pour la valeur de Signal et souhaite être averti chaque fois que la valeur de Signal change. Lorsque la valeur du Signal est modifiée, le Signal avertira tous ses dépendants , leur permettant de réagir au changement de la valeur du Signal . Cela fait du Signal l’élément central d’une application réactive, car il permet à différentes parties de l’application de se mettre à jour automatiquement en réponse aux modifications des données.

Alors, comment peut-on ajouter des dépendants (consommateur) à Signal ?

Nous pouvons ajouter des consommateurs en utilisant des fonctions d’effet et calculées .

effet

Parfois, lorsqu’un signal a une nouvelle valeur, nous pouvons avoir besoin d’ajouter un effet secondaire. Pour ce faire, nous pouvons utiliser la fonction effect() .

Effect planifie et exécute une fonction à effet secondaire dans un contexte réactif.

Signature de la fonction effet :

 effet d'exportation de la fonction  (     effectFn: () => EffectCleanupFn | void , options?: CreateEffectOptions ): EffectRef
Comment utiliser l’effet

La fonction à l’intérieur de l’ effet sera réévaluée avec tout changement qui se produit dans les signaux appelés à l’intérieur. Plusieurs signaux peuvent être ajoutés à la fonction d’effet .

🔍 Je vais essayer d’expliquer le travail derrière la fonction d’effet : 🔍

lorsque nous déclarons une fonction d’effet , le effectFn passé en argument sera ajouté à la liste des consommateurs de tous les signaux utilisés par le effectFn , comme les films dans notre exemple. ( Les signaux utilisés par l’ effectFn seront les producteurs).

Ensuite, lorsque le signal a une nouvelle valeur en utilisant les opérateurs set , update ou mutate , l’ effetFn sera réévalué avec la nouvelle valeur du signal (le producteur informe tous les consommateurs des nouvelles valeurs).

La effect() fonction renvoie un EffectRef, qui est un effet réactif global qui peut être détruit manuellement. An EffectRefa une opération de destruction .

  • destroy() : 🧹 Arrêtez l’effet, en le supprimant de toutes les exécutions planifiées à venir.

calculé

Que se passe-t-il s’il existe une autre valeur qui dépend des valeurs d’autres signaux et qui doit être recalculée 🔄 chaque fois que l’une de ces dépendances change ?

Dans ce cas, nous pouvons utiliser une computed()fonction pour créer un nouveau signal qui se met automatiquement à jour chaque fois que ses dépendances changent.

computed()crée un signal de mémorisation, qui calcule sa valeur à partir des valeurs d’un certain nombre de signaux d’entrée.

Signature de la fonction calculée :

 fonction d'exportation calculée<T>( 
calcul : () => T, égal : ValueEqualityFn <T> = defaultEquals) : Signal <T>
Comment utiliser calculé

Ainsi, la fonction calculée renverra un autre signal, tous les signaux utilisés par le calcul seront suivis en tant que dépendances et la valeur du nouveau signal sera recalculée chaque fois que l’une de ces dépendances changera.

Notez que la computedfonction renvoie a Signal et non a WritableSignal, ce qui signifie qu’elle ne peut pas être modifiée manuellement à l’aide de méthodes telles que setupdateou mutate. Au lieu de cela, il est mis à jour automatiquement chaque fois que l’un de ses parents dépendants signale des changements.

et maintenant nous pouvons ajouter et effectuer ou créer un autre signal avec une fonction calculée basée sur ce nouveau signal.

Tout changement de valeurs sera maintenant propagé dans le graphique des dépendances 🌳.

C’est ça 🤩! Dans cet article, nous avons découvert les signaux angulaires, ce qu’ils sont, pourquoi nous en avons besoin et comment les utiliser dans nos applications. J’espère que cela vous a aidé à comprendre la puissance des signaux.

Pour illustrer ces concepts, j’ai créé un projet 🎯 qui explique les signaux angulaires et montre comment créer et mettre à jour des signaux, utiliser des effets et créer des valeurs calculées. Dans le GIF suivant, vous pouvez voir l’application en action, et vous pouvez trouver le code complet dans ce référentiel GitHub . Si vous trouvez le code utile, n’hésitez pas à lui donner une étoile⭐️.

Merci d’avoir lu, n’oubliez pas de soutenir cet article avec votre 👏 pour aider à le partager avec plus de personnes. Et assurez-vous de me suivre sur twitter ou medium pour des articles plus passionnants à l’avenir ! 🔥