Routeur Angular 2

Philippe Martin
Angular
Published in
7 min readOct 6, 2016

--

Traduction de l’article Angular 2 Router de Victor Savkin.

La gestion des changements d’état est une des parties les plus difficiles dans la construction d’une application. C’est particulièrement vrai sur le web, où vous devez aussi vous assurer que l’état est reflété dans l’URL. En outre, nous voulons souvent découper une application en plusieurs paquets que nous chargeons à la demande. Faire ceci de manière transparente n’est pas trivial.

Le Routeur Angular 2 résout ces problèmes. En utilisant le routeur, vous pouvez préciser de manière déclarative les états de l’application, gérer les changements d’état tout en prenant soin de l’URL et enfin charger des paquets à la demande.

Cet article est basé sur le livre « Angular 2 Router » que vous pouvez trouver ici https://leanpub.com/router. Le livre va au-delà d’un simple guide de démarrage et décrit le routeur en profondeur. Le modèle mental, les contraintes de design et les subtilités de l’API — tout est couvert. Si vous aimez l’article, consultez le livre !

Le diagramme suivant illustre les cinq opérations de base du routeur Angular.

Le routeur Angular prend une URL, puis :

1. Applique les redirections
2. Reconnaît les états du routeur
3. Exécute les gardes et résout les données
4. Active tous les composants nécessaires
5. Gère la navigation

Format des URLs

Puisque je vais utiliser beaucoup d’URLs dans les exemples suivants, examinons rapidement le format des URLs.

/inbox/33(popup:compose)/inbox/33;open=true/messages/44

Comme vous pouvez le voir, le routeur utilise des parenthèses pour sérialiser des segments secondaires (par exemple, popup:compose), le deux-points pour préciser l’outlet et la syntaxe ’;paramètre=valeur’ (par exemple, open=true) pour préciser des paramètres spécifiques à une route.

Dans les exemples suivants nous considérons que nous avons donné la configuration suivante au routeur et que nous naviguons vers ‘/inbox/33/messages/44’.

Appliquer les redirections

Le routeur obtient une URL de l’utilisateur soit lorsqu’il clique sur un lien, soit lorsqu’il met à jour directement la barre de navigation. La première chose que fait le routeur avec cette URL est d’appliquer les redirections.

Qu’est-ce qu’une redirection ?

Une redirection est la substitution d’un segment d’URL. Une redirection peut être soit locale soit absolue. Une redirection locale remplace un seul segment de l’URL par un autre. Une redirection absolue remplace l’URL complète. Une redirection est locale à moins de préfixer l’url avec un slash.

La configuration fournie contient une seule règle de redirection : { path: ‘’, pathMatch: ‘full’, redirectTo: ‘/inbox’ }, c’est-à-dire, remplace ’/’ par ’/inbox’. Cette redirection est absolue car la valeur de redirectTo commence par un slash.

Puisque nous naviguons vers ‘/inbox/33/messages/44’ et non ‘/’, le routeur n’appliquera aucune redirection et l’URL restera inchangée.

Reconnaître les états

Ensuite, le routeur va produire un état de routeur à partir de l’URL. Pour comprendre le fonctionnement de cette étape, nous devons en apprendre un peu plus sur la façon dont le routeur fait la mise en correspondance de l’URL.

Le routeur traverse le tableau des routes, une par une, et contrôle si l’URL commence par le chemin d’une de ces routes. Dans notre cas il va trouver que ‘/inbox/33/messages/44’ commence par ‘:folder’. Ce faisant, le routeur va définir le paramètre folder à ‘inbox’ puis prendre les éléments de configuration enfants, la suite de l’URL ‘33/messages/44’ et continuer la mise en correspondance. Par conséquent, le paramètre id sera défini à ‘33’ et, finalement, la route ‘messages/:id’ sera mise en correspondance avec le second paramètre id défini à ‘44’.

Si le chemin pris dans la configuration ne “consomme” pas l’URL entière, le routeur fait marche arrière pour essayer un chemin alternatif. S’il s’avère impossible de faire correspondre l’URL entière, la navigation échoue. Mais si ça marche, l’état du routeur représentant le futur état de l’application sera construit.

Un état de routeur consiste en un ensemble de routes activées. Et chaque route activée peut être associée à un composant. De plus, notez que nous avons toujours une route activée associée au composant racine de l’application.

Exécuter les gardes

À ce stade nous avons un futur état de routeur. Le routeur va ensuite vérifier que la transition vers ce nouvel état est permis. Il va pour cela exécuter des gardes. Nous verrons les gardes en détail dans de futurs articles. Pour l’instant, il est suffisant de dire qu’un garde est une fonction que le routeur exécute pour être sûr que la navigation vers une URL donnée est permise.

Résoudre les données

Après avoir exécuté les gardes, le routeur va résoudre les données. Pour voir comment cela fonctionne, nous allons modifier notre configuration définie plus haut.

Où ConversationsResolver est défini comme suit :

Pour terminer, nous devons enregistrer ConversationsResolver au bootstrap de notre application.

De cette façon, lors de la navigation vers ‘/inbox’, le routeur va créer un état de routeur avec une route activée pour le composant des conversations. Cette route aura le paramètre folder défini à ‘inbox’. En utilisant ce paramètre avec l’utilisateur courant, nous pouvons récupérer toutes les conversations de la boîte de réception pour cet utilisateur.

Nous pouvons accéder aux données résolues en injectant l’objet de route activée dans le composant des conversations.

Activer les composants

À ce stade, nous avons un état de routeur. Le routeur peut maintenant activer cet état en instanciant tous les composants nécessaires et en les plaçant dans les outlets de routeur appropriés.

Pour en comprendre le fonctionnement, voyons comment utiliser des outlets de routeur dans un modèle de composant.

Le composant racine de notre application a deux outlets : principal et popup.

D’autres composants, comme ConversationCmp, en contiennent uniquement un.

Imaginons maintenant que nous naviguons vers ‘/inbox/33/messages/44(popup:compose)’.

Voilà ce que le routeur va faire : il va d’abord instancier ConversationCmp et le placer dans l’outlet principal du composant racine. Il va ensuite placer une nouvelle instance de ComposeCmp dans l’outlet ‘popup’. Pour finir, Il va créer une nouvelle instance de MessageCmp et la placer dans l’outlet principal du composant conversation fraîchement créé.

Utiliser les paramètres

Les composants reposent souvent sur des paramètres ou des données résolues. Par exemple, le composant conversation doit vraisemblablement accéder à l’objet conversation. Nous récupérons les paramètres et les données en injectant ActivatedRoute.

Si nous naviguons de ‘/inbox/33/messages/44(popup:compose)’ vers ‘/inbox/34/messages/45(popup:compose)’, l’observable de données va émettre un nouveau map avec le nouvel objet et le composant conversation affichera les informations de la Conversation 34.

Comme vous le voyez le routeur expose les paramètres et les données sous forme d’observables, ce qui est pratique la plupart du temps, mais pas toujours. Nous voulons parfois un instantané de l’état que nous pouvons examiner immédiatement.

Navigation

Ainsi à ce stade le routeur a créé un état de routeur et instancié les composants. Nous voulons ensuite pouvoir naviguer de cet état de routeur vers un autre. Il y a deux manières d’accomplir ceci : de manière impérative, en appelant ‘router.navigate’ ou de manière déclarative, en utilisant une directive RouterLink.

Navigation impérative

Pour naviguer de manière impérative, injectez le service Router et appelez navigate.

RouterLink

Une autre manière de naviguer est d’utiliser la directive RouterLink.

Cette directive va également mettre à jour l’attribut href lorsqu’elle est appliquée à un élément de lien `<a>`, ce qui est SEO-friendly, et le clic-droit ouvrir-dans-un-nouvel-onglet que nous attendons de liens ordinaires fonctionnera.

Pour résumer

Examinons toutes les opérations du routeur Angular une nouvelle fois.

Lors du chargement par le navigateur de l’URL ‘/inbox/33/messages/44(popup:compose)’, le routeur va faire les choses suivantes. Tout d’abord, il va appliquer les redirections. Dans cet exemple, aucune d’elles ne sera appliquée et l’URL restera inchangée. Le routeur va ensuite utiliser cette URL pour construire un nouvel état de routeur.

Ensuite, le routeur va instancier les composants conversation et message.

Maintenant, disons que le composant message contient le lien suivant dans son modèle :

<a [routerLink]=”
['/', {outlets: {popup: [‘message’, this.id]}}]”>Edit</a>

La directive de lien de routeur va lire le tableau et définir l’attribut href à ‘/inbox/33/messages/44(popup:message/44)’.

Maintenant, disons que l’utilisateur déclenche une navigation en cliquant sur le lien. Le routeur va prendre l’URL ainsi construite et recommencer le processus depuis le début : il va voir que les composants conversation et message sont déjà en place. Il n’y a donc rien à faire ici. Il va par contre créer une instance de `PopupMessageCmp` et la placer dans l’outlet popup. Une fois fait, le routeur va mettre à jour la propriété location avec la nouvelle URL.

Ce fut intense — c’est beaucoup d’informations ! Mais nous avons appris pas mal de choses. Nous avons vu les opérations de base du routeur Angular : application des redirections, reconnaissance d’état, exécution de gardes et résolution des données, activation de composant, navigation. Pour finir, nous avons examiné un exemple e2e montrant le routeur en action.

Suivez @victorsavkin pour en savoir plus sur Angular et TypeScript.

--

--