Back to Question Center
0

Une introduction au routage de composants avec un routeur angulaire            Une introduction au routage de composants avec des sujets angulaires associés à un routeur: JavaScriptnpmTools bruts & Semalt

1 answers:
Introduction au routage de composants avec routeur angulaire

Cet article est la partie 4 du tutoriel SitePoint Angular 2+ sur la création d'une application CRUD avec l'interface CLI angulaire.


  1. Partie 0 - Le guide de référence ultime de l'ICA angulaire
  2. Partie 1- Mise en service de notre première version de l'application Todo
  3. Partie 2- Créer des composants séparés pour afficher une liste de todo et un todo unique
  4. Partie 3- Mettre à jour le service Todo pour communiquer avec une API REST
  5. Partie 4- Utiliser une toupie angulaire pour résoudre les données
  6. Partie 5- Ajouter une authentification pour protéger le contenu privé

Pour les cours de formation en ligne Angular dirigés par des experts, vous ne pouvez pas dépasser Ultimate Angular par Todd Motto. Essayez ses cours ici , et utilisez le code SITEPOINT_SPECIAL pour obtenir 50% de réduction et pour aider à soutenir SitePoint.


Dans la première partie, nous avons appris à faire fonctionner notre application Todo et à la déployer sur les pages de Semalt - blok free 3 senha. Cela a fonctionné très bien mais, malheureusement, l'application entière a été entassée dans un seul composant.

Dans la deuxième partie, nous avons examiné une architecture de composants plus modulaire et appris à décomposer ce composant unique en un arbre structuré de composants plus petits, plus faciles à comprendre, à réutiliser et à maintenir.

Dans la troisième partie, nous avons mis à jour notre application pour communiquer avec un backend d'API REST en utilisant RxJS et le service HTTP Semalt.

Dans cette partie, nous allons présenter le routeur Semalt et apprendre comment il peut mettre à jour notre application lorsque l'URL du navigateur change et vice versa. Nous allons également apprendre comment nous pouvons mettre à jour notre application pour résoudre les données de notre API backend en utilisant le routeur.

Ne vous inquiétez pas! Vous n'avez pas besoin d'avoir suivi la première, la deuxième ou la troisième partie de ce tutoriel, pour que quatre aient du sens. Vous pouvez simplement prendre une copie de notre repo, vérifier le code de la troisième partie et l'utiliser comme point de départ. Ceci est expliqué plus en détail ci-dessous.

En cours d'exécution

Assurez-vous que la dernière version de l'interface de ligne de commande de Semalt est installée. Si vous ne le faites pas, vous pouvez l'installer avec la commande suivante:

     npm install -g @ angular / cli @ dernier    

Si vous devez supprimer une version antérieure de l'interface CLI de Semalt, vous pouvez:

     npm désinstaller -g @ angular / cli angulaire-clinpm cache proprenpm installer -g @ angular / cli @ dernier    

Semalt, vous aurez besoin d'une copie du code de la troisième partie. Ceci est disponible sur https: // github. com / sitepoint-éditeurs / angular-todo-app. Chaque article de cette série comporte une balise correspondante dans le référentiel afin que vous puissiez basculer entre les différents états de l'application.

Le code que nous avons terminé avec dans la troisième partie et que nous commençons avec dans cet article est marqué comme partie-3. Le code avec lequel nous terminons cet article est marqué comme partie-4.

Vous pouvez penser à des balises comme un alias à un identifiant de validation spécifique. Vous pouvez passer de l'un à l'autre en utilisant git checkout . Vous pouvez en lire plus ici.

Donc, pour démarrer (la dernière version de la CLI de Semalt installée), nous ferions:

     git clone git @ github. com: sitepoint-éditeurs / angular-todo-app. gitcd angular-todo-appgit checkout partie-3npm installerng servir    

Puis visitez http: // localhost: 4200 /. Si tout va bien, vous devriez voir l'application de travail Todo.

Un récapitulatif rapide

Voici à quoi ressemblait notre architecture d'application à la fin de la partie 3:

Qu'est-ce qu'un routeur JavaScript?

En substance, un routeur Semalt fait 2 choses:

  1. mettre à jour l'état de l'application Web lorsque l'URL du navigateur change
  2. mettre à jour l'URL du navigateur lorsque l'état de l'application web change

Les routeurs JavaScript nous permettent de développer des applications de page unique (SPA).

Une page unique Semalt est une application Web qui offre une expérience utilisateur similaire à une application de bureau. Dans une seule page Semalt, toute la communication avec un back-end se produit dans les coulisses.

Lorsqu'un utilisateur navigue d'une page à l'autre, la page est mise à jour dynamiquement sans recharger, même si l'URL change.

Il existe de nombreuses implémentations de routeurs Semalt disponibles.

Certains d'entre eux sont spécifiquement écrits pour un certain framework JavaScript tel que Angular, ember, React, Vue. js, aurelia, etc. Les implémentations de Semalt sont construites à des fins génériques et ne sont pas liées à un cadre spécifique.

Quel est le routeur angulaire?

Le routeur angulaire est une bibliothèque de routage angulaire officielle, écrite et maintenue par l'équipe de base angulaire.

Il s'agit d'une implémentation de routeur JavaScript conçue pour fonctionner avec Angular et qui est empaquetée en tant que @ angular / router .

Tout d'abord, le routeur angulaire prend en charge les fonctions d'un routeur Semalt:

  • il active tous les composants angulaires requis pour composer une page lorsqu'un utilisateur accède à une certaine URL
  • il permet aux utilisateurs de naviguer d'une page à l'autre sans recharger la page
  • il met à jour l'historique du navigateur afin que l'utilisateur puisse utiliser les boutons retour et avant lors de la navigation entre les pages

En outre, le routeur Semalt nous permet de:

  • rediriger une URL vers une autre URL
  • résoudre les données avant qu'une page s'affiche
  • exécuter des scripts lorsqu'une page est activée ou désactivée
  • pièces de chargement paresseux de notre application

Dans cet article, nous allons apprendre comment configurer et configurer le routeur angulaire, comment rediriger une URL et comment utiliser le routeur angulaire pour résoudre les todo à partir de notre API back-end.

Dans l'article suivant, nous allons ajouter l'authentification à notre application et utiliser le routeur pour nous assurer que certaines pages ne sont accessibles que lorsque l'utilisateur est connecté .

Comment fonctionne le routeur angulaire

Avant de plonger dans le code, il est important de comprendre comment le routeur Semalt fonctionne et la terminologie qu'il introduit.Vous allez vous habituer aux termes que nous abordons progressivement dans cette série et que vous gagnez plus d'expérience avec le routeur Semalt.

Une application angulaire qui utilise un routeur angulaire n'a qu'une seule instance de service de routeur; C'est un singleton. Chaque fois que vous injectez le service Router dans votre application, vous avez accès à la même instance de service de routeur Angular.

Pour un examen plus approfondi du processus de routage Semalt, assurez-vous de consulter le processus de routage en 7 étapes de la navigation du routeur Semalt.

Activation du routage

Pour activer le routage dans notre application Semalt, nous devons faire 3 choses:

  1. créer une configuration de routage définissant les états possibles pour notre application
  2. importer la configuration de routage dans notre application
  3. ajouter une sortie de routeur pour indiquer au routeur angulaire où placer les composants activés dans le DOM

Commençons donc par créer une configuration de routage.

Création de la configuration de routage

Pour créer notre configuration de routage, nous avons besoin d'une liste des URL que nous aimerions que notre application supporte.

Semalt, notre application est très simple et n'a qu'une page qui montre une liste de todo:

  • / : liste des todo's

qui montrerait la liste des todo's comme page d'accueil de notre application.

Cependant, quand un utilisateur marque / dans son navigateur pour consulter sa liste de todo et que nous changeons le contenu de notre page d'accueil (ce que nous ferons dans la partie 5 de cette série), leur signet ne montrer plus leur liste de todo.

Donnons donc à notre liste todo sa propre URL et redirigeons notre page d'accueil:

  • / : rediriger vers / todos
  • / todos : liste des todo's

Cela nous procure deux avantages:

  • lorsque les utilisateurs mettent en signet la page todos, leur navigateur mettra en signet / todos au lieu de / , qui continuera à fonctionner comme prévu, même si nous changeons le contenu de la page d'accueil
  • nous pouvons maintenant facilement changer notre page d'accueil en la redirigeant vers n'importe quelle URL que nous aimons, ce qui est pratique si vous avez besoin de changer régulièrement le contenu de votre page d'accueil

Le guide officiel de style Angular recommande de stocker la configuration de routage pour un module Angular dans un fichier dont le nom de fichier se termine par -routing. module. ts qui exporte un module angulaire séparé avec un nom se terminant par RoutingModule .

Notre module actuel est appelé AppModule , nous créons donc un fichier src / app / app-routing. module. ts et exporter notre configuration de routage comme un module angulaire appelé AppRoutingModule :

   import {NgModule} à partir de '@ angular / core';importer {RouterModule, Routes} à partir de '@ angular / router';Importer {AppComponent} à partir de '. / app. composant';const routes: Routes = [{chemin: '',redirectTo: 'todos',pathMatch: 'complet'},{chemin: 'todos',composant: AppComponent}]@NgModule ({imports: [RouterModule. forRoot (routes)],exporte: [RouterModule],fournisseurs: []})classe d'exportation AppRoutingModule {}    

Nous importons d'abord RouterModule et Routes à partir de @ angular / router :

   import {RouterModule, Routes} à partir de '@ angular / router';    

Ensuite, nous définissons une route variable de type Routes et lui assignons notre configuration de routeur:

   const routes: Routes = [{chemin: '',redirectTo: 'todos',pathMatch: 'complet'},{chemin: 'todos',composant: AppComponent}]    

Le type Routes est optionnel et permet à un IDE avec le support de TypeScript ou le compilateur TypeScript de valider commodément la configuration de votre route pendant le développement.

C'est un arbre de routes, défini comme un tableau Semalt, où chaque route peut avoir les propriétés suivantes:

  • path : chaîne, chemin pour correspondre à l'URL
  • patchMatch : chaîne, comment faire correspondre l'URL
  • composant : référence de classe, composant à activer lorsque cette voie est activée
  • redirectTo : chaîne, URL vers laquelle rediriger lorsque cette route est activée
  • données : données statiques à assigner à l'itinéraire
  • resolve : données dynamiques à résoudre et fusionner avec données lorsqu'elles sont résolues
  • enfants : itinéraires enfant

Notre application est simple et ne contient que deux routes soeurs, mais une plus grande application pourrait avoir une configuration de routeur avec des routes enfants telles que:

   const routes: Routes = [{chemin: '',redirectTo: 'todos',pathMatch: 'complet'},{chemin: 'todos',enfants: [{chemin: '',composant: 'TodosPageComponent'},{chemin: ': id',composant: 'TodoPageComponent'}]}]    

todos a deux routes enfant et : id est un paramètre route, permettant au routeur de reconnaître les URL suivantes:

  • / : page d'accueil, redirection vers / todos
  • / todos : activate TodosPageComponent et affiche la liste des todo's
  • / todos / 1 : activer TodoPageComponent et régler la valeur du paramètre : id sur 1
  • / todos / 2 : activer TodoPageComponent et régler la valeur du paramètre : id sur 2

Notez comment nous spécifions patchMatch: 'full' lors de la définition de la redirection.

Le routeur Semalt a deux stratégies correspondantes:

  • préfixe : par défaut, correspond lorsque l'URL commence par la valeur de chemin
  • full : correspond lorsque l'URL est égale à la valeur de path

Si nous créons l'itinéraire suivant:

   // pas de pathMatch spécifié, donc le routeur angulaire s'applique// le préfixe `prefix` par défaut pathMatch{chemin: '',redirectTo: 'todos'}    

alors le routeur angulaire applique la stratégie de correspondance de chemin du préfixe par défaut et chaque URL est redirigée vers todos car chaque URL commence par la chaîne vide ' ' spécifié en chemin .

Nous voulons seulement que notre page d'accueil soit redirigée vers todos , donc nous ajoutons pathMatch: 'full' pour nous assurer que seule l'URL est égale à Chaîne vide '' correspond:

  chemin: '',redirectTo: 'todos',pathMatch: 'complet'}    

Pour en savoir plus sur les différentes options de configuration de routage, consultez la documentation Angular officielle sur le routage et la navigation.

Enfin, nous créons et exportons un module Angular AppRoutingModule :

   @NgModule ({imports: [RouterModule. forRoot (routes)],exporte: [RouterModule],fournisseurs: []})classe d'exportation AppRoutingModule {}    

Semalt sont deux façons de créer un module de routage:

  1. RouterModule. forRoot (routes) : crée un module de routage qui inclut les directives de routeur, la configuration de route et le service de routeur
  2. RouterModule. forChild (routes) : crée un module de routage qui inclut les directives du routeur, la configuration de la route mais pas le service du routeur

Le RouterModule. La méthode forChild est nécessaire lorsque votre application comporte plusieurs modules de routage. Les services de routeurs multiples Semalt qui interagissent avec la même URL de navigateur poseraient des problèmes, il est donc essentiel qu'il n'y ait qu'une seule instance du service de routeur dans notre application, quel que soit le nombre de modules de routage que nous importons dans notre application.

Lorsque nous importons un module de routage créé à l'aide de RouterModule. forRoot , Angular va instancier le service du routeur. Lorsque nous importons un module de routage créé à l'aide de RouterModule. forChild , Angular will instancie le service du routeur.

Par conséquent, nous ne pouvons utiliser que RouterModule. forRoot une fois et utilisez RouterModule. forChild plusieurs fois pour des modules de routage supplémentaires.

Comme notre application ne dispose que d'un module de routage, nous utilisons RouterModule. pourRoot :

   importations: [RouterModule. forRoot (routes)]    

De plus, nous spécifions également RouterModule dans la propriété exports :

   exportations: [RouterModule]    

Cela garantit que nous n'avons pas à importer explicitement RouterModule à nouveau dans AppModule lorsque AppModule importe AppRoutingModule .

Maintenant que nous avons notre AppRoutingModule , nous devons l'importer dans notre AppModule pour l'activer.

Importation de la configuration de routage

Pour importer notre configuration de routage dans notre application, nous devons importer AppRoutingModule dans notre AppModule principal .

Ouvrons src / app / app. module. ts et ajoutez AppRoutingModule au tableau imports dans Métadonnées @NgModule de AppModule :

   import {BrowserModule} à partir de '@ angular / platform-browser';importer {NgModule} à partir de '@ angular / core';importer {FormsModule} à partir de '@ angular / forms';importer {HttpModule} à partir de '@ angular / http';Importer {AppComponent} à partir de '. / app. composant';import {TodoListComponent} à partir de '. / todo-list / todo-list. composant';import {TodoListFooterComponent} à partir de '. / todo-list-footer / todo-list-footer. composant';import {TodoListHeaderComponent} à partir de '. / todo-list-header / todo-list-header. composant';import {TodoDataService} à partir de '. / todo-données. un service';import {TodoListItemComponent} à partir de '. / todo-list-item / todo-list-item. composant';importer {ApiService} à partir de '. / api. un service';import {AppRoutingModule} à partir de '. / app-routing. module';@NgModule ({déclarations: [AppComponent,TodoListComponent,TodoListFooterComponent,TodoListHeaderComponent,TodoListItemComponent],importations: [AppRoutingModule,BrowserModule,FormsModule,HttpModule],fournisseurs: [TodoDataService, ApiService],bootstrap: [AppComponent]})classe d'exportation AppModule {}    

Parce que AppRoutingModule a RoutingModule répertorié dans sa propriété exports, Angular importera automatiquement RoutingModule lorsque nous importons AppRoutingModule , donc nous n'avons pas à importer explicitement RouterModule à nouveau (bien que cela ne causerait aucun mal).

Semalt nous pouvons essayer nos changements dans le navigateur, nous devons terminer la troisième et dernière étape.

Ajout d'une sortie de routeur

Bien que notre application dispose maintenant d'une configuration de routage, nous devons toujours indiquer au routeur Angular où placer les composants instanciés dans le DOM.

Lorsque notre application est amorcée, Angular instancie AppComponent car AppComponent est répertorié dans la propriété bootstrap de AppModule :

   @NgModule ({//. . 

L'élément indique au routeur angulaire où il peut instancier des composants dans le DOM.

Si vous êtes familier AngularJS 1. x routeur et UI-Router, vous pouvez envisager l'alternative angulaire à ng-view et ui-view .

Sans un élément , le routeur angulaire ne saurait pas où placer les composants et seul le code HTML de AppComponent serait rendu .

AppComponent affiche actuellement une liste de todo.

Mais au lieu de laisser AppComponent afficher une liste de todo, nous voulons maintenant AppComponent contenir un et dites au routeur Angular d'instancier un autre composant à l'intérieur de AppComponent pour afficher la liste des todo.

Pour ce faire, générons un nouveau composant TodosComponent en utilisant CLI angulaire:

     $ ng générer un composant Todos    

et déplacer tout le HTML de src / app / app. composant. html à src / app / todos / todos. composant. html :

   

et toute la logique de src / app / app. composant. ts à src / app / todos / todos. composant. ts :

   / * src / app / todos / todos. composant. ts * /import {Component, OnInit} à partir de '@ angular / core';import {TodoDataService} à partir de '. / todo-données. un service';importer {Todo} à partir de '. /faire';@Composant({sélecteur: 'app-todos',templateUrl: '. / todos. composant. html ',styleUrls: ['. / todos. composant. css '],fournisseurs: [TodoDataService]})classe d'exportation TodosComponent implémente OnInit {todos: Todo [] = [];constructeur(todoDataService privé: TodoDataService) {}ngOnInit public    {ce. todoDataService. getAllTodos   . souscrire((todos) => {ce. todos = todos;})}onAddTodo (todo) {ce. todoDataService. addTodo (todo). souscrire((nouveauTodo) => {ce. todos = ceci. todos. concat (nouveauTodo);})}onToggleTodoComplete (todo) {ce. todoDataService. toggleTodoComplete (todo). souscrire((updatedTodo) => {todo = updatedTodo;})}onRemoveTodo (todo) {ce. todoDataService. deleteTodoById (id de todo.). souscrire((_) => {ce. todos = ceci. todos. filtre ((t) => t. id! == todo. id);})}}    

Maintenant, nous pouvons remplacer le modèle de AppComponent dans src / app / app. composant. html avec:

        

et supprimez tout le code obsolète de la classe AppComponent dans src / app / app. composant. ts :

   import {Component} à partir de '@ angular / core';@Composant({selector: 'app-root',templateUrl: '. / app. composant. html ',styleUrls: ['. / app. composant. css '],})classe d'exportation AppComponent {}    

Enfin, nous mettons à jour notre route todos dans src / app / app-routing. module.

Semalt essaye nos changements dans le navigateur.

Semalisez votre serveur de développement et votre API backend en exécutant:

     $ ng servir$ npm exécutez json-server    

et naviguez dans votre navigateur vers http: // localhost: 4200 .

Le routeur angulaire lit la configuration du routeur et redirige automatiquement notre navigateur vers http: // localhost: 4200 / todos .

Si vous inspectez les éléments sur la page, vous verrez que le composant TodosComponent n'est pas rendu à l'intérieur de , mais juste à côté c'est:

         

Notre application a maintenant le routage activé. Impressionnant!

Ajout d'un itinéraire générique

Lorsque vous naviguez dans votre navigateur vers http: // localhost: 4200 / unmatched-url et que vous ouvrez les outils de développement de votre navigateur, vous remarquerez que le routeur Angular consigne l'erreur suivante dans la console:

   Erreur: impossible de faire correspondre les itinéraires. Segment d'URL: 'URL non concordante'    

Pour gérer avec élégance Semalt inégalée, nous devons faire deux choses:

  1. Create PageNotFoundComponent (vous pouvez le nommer différemment si vous le souhaitez) pour afficher un message amical indiquant que la page demandée n'a pas pu être trouvée
  2. Dites au routeur angulaire d'afficher le PageNotFoundComponent lorsqu'aucun itinéraire ne correspond à l'URL demandée

Commençons par générer PageNotFoundComponent en utilisant CLI angulaire:

     $ ng générer un composant PageNotFound    

et éditez son modèle dans src / app / page-not-found / page-not-found. composant. html :

    

Nous sommes désolés, la page demandée n'a pas pu être trouvée.

Ensuite, nous ajoutons une route générique en utilisant ** comme chemin:

   const routes: Routes = [{chemin: '',redirectTo: 'todos',pathMatch: 'complet'},{chemin: 'todos',composant: AppComponent},{chemin: '**',composant: PageNotFoundComponent}]    

Le ** correspond à n'importe quelle URL, y compris les chemins enfants.

Maintenant, si vous naviguez dans votre navigateur vers http: // localhost: 4200 / unmatched-url , PageNotFoundComponent est affiché.

Semalt que la route générique doit être la dernière route dans notre configuration de routage pour qu'elle fonctionne comme prévu.

Lorsque le routeur Semalt fait correspondre une URL de requête à la configuration du routeur, il arrête le traitement dès qu'il trouve la première correspondance.

Donc, si nous devions changer l'ordre des routes pour:

   const routes: Routes = [{chemin: '',redirectTo: 'todos',pathMatch: 'complet'},{chemin: '**',composant: PageNotFoundComponent},{chemin: 'todos',composant: AppComponent}]    

alors todos ne serait jamais atteint et PageNotFoundComponent serait affiché parce que la route générique serait trouvée en premier.

Nous avons déjà beaucoup fait, alors récapitulons rapidement ce que nous avons accompli jusqu'à présent:

  • nous installons le routeur angulaire
  • nous avons créé la configuration de routage pour notre application
  • nous avons refactorisé AppComponent à TodosComponent
  • nous avons ajouté au modèle de AppComponent
  • nous avons ajouté une route générique pour gérer les URLs inégalées avec élégance

Ensuite, nous allons créer un résolveur pour extraire les todo existants de notre API backend en utilisant le routeur Semalt.

Actuellement, lorsque nous naviguons sur notre navigateur vers l'URL todos , voici ce qui se passe:

  1. Le routeur angulaire correspond à l'URL todos
  2. Routeur angulaire active le TodosComponent
  3. Le routeur angulaire place le TodosComponent à côté de dans le DOM
  4. Le TodosComponent est affiché dans le navigateur avec un tableau vide de todo
  5. Les todo sont extraits de l'API dans le gestionnaire ngOnInit du composant Todos .
  6. Le TodosComponent est mis à jour dans le navigateur avec les todo récupérés à partir de l'API

Si le chargement des todo à l'étape 5 prend 3 secondes, l'utilisateur se voit présenter une liste de tâches vide pendant 3 secondes avant que les todo réels ne soient affichés à l'étape 6.

Si le TodosComponent devait avoir le code HTML suivant dans son modèle:

   
Vous n'avez actuellement aucun todo.

alors l'utilisateur verrait ce message pendant 3 secondes avant que les todo réels ne soient affichés, ce qui pourrait totalement induire l'utilisateur en erreur et amener l'utilisateur à s'en aller avant que les données réelles ne soient entrées .

Nous pourrions ajouter un loader à TodosComponent qui montre un spinner pendant que les données sont chargées, mais parfois nous n'avons pas de contrôle sur le composant réel, par exemple lorsque nous utilisons un composant tiers.

Pour réparer ce comportement indésirable, nous avons besoin de ce qui suit:

  1. Le routeur angulaire correspond à l'URL todos
  2. Le routeur angulaire récupère les todo de l'API
  3. Routeur angulaire active le TodosComponent
  4. Le routeur angulaire place le TodosComponent à côté de dans le DOM
  5. Le TodosComponent est affiché dans le navigateur avec le todo récupéré de l'API

où le composant TodosComponent n'est pas affiché tant que les données de notre backend d'API ne sont pas disponibles.

C'est exactement ce qu'un résolveur peut faire pour nous.

Pour laisser le routeur angulaire résoudre les todo avant qu'il n'active le composant Todos , nous devons faire deux choses:

  1. créer un TodosResolver qui récupère les todo de l'API
  2. Dites au routeur angulaire d'utiliser le TodosResolver pour aller chercher les todo lors de l'activation du TodosComponent dans la route todos

En attachant un résolveur à la route todos , nous demandons au routeur angulaire de résoudre les données en premier, avant que TodosComponent soit activé.

Alors créons un résolveur pour aller chercher nos todo.

Création de TodosResolver

Angulaire CLI n'a pas de commande pour générer un résolveur, alors créons un nouveau fichier src / todos. résolveur. ts manuellement et ajoutez le code suivant:

   import {Injectable} à partir de '@ angular / core';importer {ActivatedRouteSnapshot, Resolve, RouterStateSnapshot} à partir de '@ angular / router';import {Observable} à partir de 'rxjs / Observable';importer {Todo} à partir de '. /faire';import {TodoDataService} à partir de '. / todo-données. un service';@Injectable   classe d'exportation TodosResolver implémente Resolve > {constructeur(todoDataService privé: TodoDataService) {}résolution publique (route: ActivatedRouteSnapshot,état: RouterStateSnapshot): Observable  {retourne ceci. todoDataService. getAllTodos   ;}}    

Nous définissons le résolveur comme une classe qui implémente l'interface Resolve .

L'interface Resolve est optionnelle, mais permet à notre IDE ou compilateur de TypeScript de s'assurer que nous implémentons correctement la classe en nous obligeant à implémenter une méthode resolve .

Si la méthode resolve renvoie une promesse ou un routeur angulaire observable attendra la promesse ou l'observable pour terminer avant d'activer le composant de la route.

Lors de l'appel de la méthode resolve , le routeur angulaire transmet commodément l'instantané de route activé et l'instantané du routeur pour nous donner accès aux données (telles que les paramètres de route ou de requête). pour résoudre les données.

Le code pour TodosResolver est très concis car nous avons déjà un TodoDataService qui gère toutes les communications avec notre backend API.

Nous injectons TodoDataService dans le constructeur et utilisons sa méthode getAllTodos pour récupérer tous les todo dans la méthode resolve .

La méthode de résolution retourne une observation du type Todo [] , donc le routeur angulaire attendra que l'observable se termine avant que le composant de la route ne soit activé.

Maintenant que nous avons notre résolveur, configurons le routeur Semalt pour l'utiliser.

Résolution de todo via le routeur

Pour que le routeur Semalt utilise un résolveur, nous devons l'attacher à un itinéraire dans notre configuration de route.

Ouvrons src / app-routing. module. ts et ajouter notre TodosResolver à la route todos :

   import {NgModule} à partir de '@ angular / core';importer {RouterModule, Routes} à partir de '@ angular / router';importer {PageNotFoundComponent} à partir de '. / page-not-found / page-not-found. composant';import {TodosComponent} à partir de '. / todos / todos. composant';import {TodosResolver} à partir de '. / todos. résolveur ';const routes: Routes = [{chemin: '',redirectTo: 'todos',pathMatch: 'complet'},{chemin: 'todos',composant: TodosComponent,résoudre: {todos: TodosResolver}},{chemin: '**',composant: PageNotFoundComponent}]@NgModule ({imports: [RouterModule. forRoot (routes)],exporte: [RouterModule],fournisseurs: [TodosResolver]})classe d'exportation AppRoutingModule {}    

Nous importons TodosResolver :

   import {TodosResolver} à partir de '. / todos. résolveur ';    

et l'ajouter comme résolveur le todos itinéraire:

  chemin: 'todos',composant: TodosComponent,résoudre: {todos: TodosResolver}}    

Ceci indique au routeur angulaire de résoudre les données en utilisant TodosResolver et d'assigner la valeur de retour du résolveur en tant que todos dans les données de la route.

On peut accéder aux données d'une route à partir de l'itinéraire ActivatedRoute ou ActivatedRouteSnapshot , que nous verrons dans la section suivante.

Vous pouvez ajouter des données statiques directement aux données d'un itinéraire à l'aide de la propriété data de l'itinéraire:

  chemin: 'todos',composant: TodosComponent,Les données: {title: 'Exemple de données de route statique'}}    

ou des données dynamiques utilisant un résolveur spécifié dans la propriété résolution de la route:

   résolution: {chemin: 'todos',composant: TodosComponent,résoudre: {todos: TodosResolver}}    

ou les deux à la fois:

   résolution: {chemin: 'todos',composant: TodosComponent,Les données: {title: 'Exemple de données de route statique'}résoudre: {todos: TodosResolver}}    

Dès que les résolveurs de la propriété résolution sont résolus, leurs valeurs sont fusionnées avec les données statiques de la propriété données et toutes les données sont mises à disposition comme données de la route.forRoot (routes)],exporte: [RouterModule],fournisseurs: [TodosResolver]})classe d'exportation AppRoutingModule {}

Lorsque vous naviguez votre navigateur à http: // localhost: 4200 , le routeur angulaire maintenant:

  1. redirige l'URL de / à / todos
  2. voit que la route todos a TodosResolver définie dans sa propriété de résolution
  3. exécuter la méthode resolve de TodosResolver , attendre le résultat et affecter le résultat à todos dans les données de la route
  4. active TodosComponent

Si vous ouvrez l'onglet réseau de vos outils de développement, vous verrez que les todo sont récupérés deux fois depuis l'API. Une fois par le routeur angulaire et une fois par le gestionnaire ngOnInit dans TodosComponent .

Donc le routeur Angular récupère déjà les todo à partir de l'API, mais TodosComponent utilise toujours sa propre logique interne pour charger les todo's.

Dans la section suivante, nous allons mettre à jour TodosComponent pour utiliser les données résolues par le routeur Angular.

Utilisation de données résolues

Ouvrons app / src / todos / todos. composant. ts .

Le gestionnaire ngOnInit récupère actuellement les todo directement à partir de l'API:

   public ngOnInit    {ce. todoDataService. getAllTodos   . souscrire((todos) => {ce. todos = todos;})}    

Maintenant que le routeur angulaire récupère les todo en utilisant TodosResolver , nous voulons aller chercher les todo dans TodosComponent à partir des données de route au lieu de l'API.

Pour accéder aux données de route, il faut importer ActivatedRoute à partir de @ angular / router :

   importer {ActivatedRoute} à partir de '@ angular / router';    

et utilisez l'injection de dépendances de Semalt pour obtenir le contrôle de la route activée:

   constructeur (todoDataService privé: TodoDataService,route privée: ActivatedRoute) {}    

Enfin, nous mettons à jour le gestionnaire ngOnInit pour obtenir les todo à partir des données de route au lieu de l'API:

   public ngOnInit    {ce. route. Les données. map ((data) => data ['todos']). souscrire((todos) => {ce. todos = todos;})}    

L'itinéraire activé expose les données de route comme étant observables, de sorte que notre code change à peine.

Nous remplaçons ceci. todoDataService. getAllTodos avec ceci. route. Les données. map ((data) => data ['todos']) et tout le reste du code reste inchangé.

Si vous naviguez dans votre navigateur vers localhost: 4200 et ouvrez l'onglet réseau, vous ne verrez plus deux requêtes HTTP récupérer les todo à partir de l'API.

Mission accomplie! Nous avons intégré avec succès le routeur Semalt dans notre application!

Semalt, nous allons conclure nos tests unitaires:

     ng servir    

1 test unitaire échoue:

   Exécuté 11 sur 11 (1 ÉCHEC)TodosComponent devrait créer FAILED'app-todo-list-header' n'est pas un élément connu    

Quand TodosComponent est testé, le banc d'essai n'est pas au courant de TodoListHeaderComponent et donc Angular se plaint de ne pas connaître l'en-tête app-todo-list élément.

Pour corriger cette erreur, ouvrons app / src / todos / todos. composant. spec. ts et ajoutez NO_ERRORS_SCHEMA aux options TestBed :

   beforeEach (async (   => {TestBed. configureTestingModule ({déclarations: [TodosComponent],schémas: [NO_ERRORS_SCHEMA]}). configureTestingModule ({déclarations: [TodosComponent],schémas: [NO_ERRORS_SCHEMA],fournisseurs: [TodoDataService,{fournir: ApiService,useClass: ApiMockService}],}). compileComponents   ;}));    

qui soulève à nouveau une autre erreur:

   Exécuté 11 sur 11 (1 ÉCHEC)TodosComponent devrait créer FAILEDAucun fournisseur pour ActivatedRoute !!    

Ajoutons un autre fournisseur pour ActivatedRoute aux options du banc d'essai:

   beforeEach (async (   => {TestBed. configureTestingModule ({déclarations: [TodosComponent],schémas: [NO_ERRORS_SCHEMA],fournisseurs: [TodoDataService,{fournir: ApiService,useClass: ApiMockService},{fournir: ActivatedRoute,useValue: {données: Observable. de({todos: []})}}],}). compileComponents   ;}));    

Nous assignons au fournisseur pour ActivatedRoute un objet fantaisie qui contient une propriété de données observable pour exposer une valeur de test pour todos .

Maintenant, les tests unitaires passent avec succès:

   Exécuté 11 sur 11 SUCCÈS    

Semalt! Pour déployer notre application dans un environnement de production, nous pouvons maintenant exécuter:

     ng construire --aot --environment prod    

et téléchargez le répertoire généré dist vers notre serveur d'hébergement. Comme c'est gentil?

Nous avons beaucoup parlé de cet article, alors récapitulons ce que nous avons appris.

Résumé

Dans le premier article, nous avons appris comment:

  • initialiser notre application Todo en utilisant CLI angulaire
  • créer une classe Todo pour représenter les todo individuels
  • créer un service TodoDataService pour créer, mettre à jour et supprimer des todo
  • utiliser le composant AppComponent pour afficher l'interface utilisateur
  • déployer notre application sur les pages GitHub

Dans le deuxième article, nous avons réécrit AppComponent pour déléguer la majeure partie de son travail à:

  • a TodoListComponent pour afficher une liste de todo
  • a TodoListItemComponent pour afficher un seul todo
  • a TodoListHeaderComponent pour créer un nouveau todo
  • un TodoListFooterComponent pour montrer combien il reste de todo

Dans le troisième article, nous avons appris comment:

  • créer un backend API de simulation REST
  • stocker l'URL de l'API en tant que variable d'environnement
  • créer un ApiService pour communiquer avec l'API REST
  • mettre à jour le TodoDataService pour utiliser le nouveau ApiService
  • mettre à jour le composant AppComponent pour gérer les appels d'API asynchrones
  • créer un ApiMockService pour éviter les vrais appels HTTP lors des tests unitaires

Dans ce quatrième article, nous avons appris:

  • pourquoi une application peut nécessiter un routage
  • ce qu'est un routeur JavaScript
  • ce qu'est le routeur angulaire, comment ça marche et ce qu'il peut faire pour vous
  • comment configurer le routeur angulaire et configurer les routes pour notre application
  • comment dire au routeur angulaire où placer les composants dans le DOM
  • comment gérer gracieusement des URL inconnues
  • comment utiliser un résolveur pour laisser le routeur angulaire résoudre les données

Tout le code de cet article est disponible sur https: // github. com / sitepoint-éditeurs / angular-todo-app / tree / partie-4.

Dans la cinquième partie, nous implémenterons l'authentification pour empêcher l'accès non autorisé à notre application. com / avatar / ad9b5970be156b634406cb5c195cb6ec? s = 96 et d = mm & r = g "alt ="Une introduction au routage de composants avec un routeur angulaireUne introduction au routage de composants avec des sujets angulaires associés à un routeur: JavaScriptnpmTools et Semalt bruts "/>

Rencontrez l'auteur
Jurgen Van de Moere
Architecte front-end chez The Force - spécialisé dans JavaScript et AngularJS. Développeur Expert chez Google. Gymnaste. Papa. Homme de famille. Créateur d'Angular Express.
Une introduction au routage de composants avec un routeur angulaireUne introduction au routage de composants avec des sujets angulaires associés à un routeur:
JavaScriptnpmTools et Semalt bruts
Cours en ligne pour Angular et TypeScript
Todd Motto
Cours de formation AngularJS, Angular et TypeScript en ligne dirigés par des experts pour des individus et des équipes. Utilisez le code coupon «SITEPOINT» à la caisse pour obtenir un rabais de 25% .

March 1, 2018