Routage > Jalon 3 : Les héros en vedette

Références

L'actualité

Librairie

L'information

Jalon 3 : Les héros en vedette

Vous avez vu comment naviguer à l'aide de la RouterLinkdirective. Maintenant, vous allez apprendre ce qui suit :
  • Organisez l'application et les itinéraires dans des zones de fonctionnalités à l'aide de modules.
  • Naviguer impérativement d'un composant à un autre.
  • Transmettez les informations obligatoires et facultatives dans les paramètres de route.
Cet exemple recrée la fonction héros dans l'épisode "Services" du didacticiel Tour of Heroes, et vous allez copier une grande partie du code de laTour of Heroes : exemple de code de service/exemple de téléchargement.

Voici comment l'utilisateur va expérimenter cette version de l'application:



Une application typique comporte plusieurs zones de fonctionnalités , chacune étant dédiée à un objectif commercial particulier.

Bien que vous puissiez continuer à ajouter des fichiers au src/app/dossier, cela n'est pas réaliste et n'est finalement pas maintenable. La plupart des développeurs préfèrent placer chaque zone de fonctionnalités dans son propre dossier.

Vous êtes sur le point de diviser l'application en différents modules de fonctionnalités, chacun ayant ses propres préoccupations. Ensuite, vous allez importer dans le module principal et naviguer parmi eux.

Ajouter la fonctionnalité des héros

Suivez ces étapes:

  • Créez un HeroesModuleavec routage dans le dossier heroes et enregistrez-le à la racine AppModule. C'est ici que vous allez mettre en place la gestion des héros.
  • Déplacez le hero-listdossier d'espace réservé qui se trouve appdans le heroesdossier.
  • Copier le contenu de heroes/heroes.component.htmlla"Services" tutoriel / exemple de téléchargementdans le hero-list.component.htmlmodèle. - Renommez le ‹h2› à ‹h2›HEROES‹/h2›. - Supprimez le ‹app-hero-detail› composant au bas du modèle.
  • Copiez le contenu de l' heroes/heroes.component.cssexemple from live dans le hero-list.component.cssfichier.
  • Copiez le contenu de l' heroes/heroes.component.tsexemple from live dans le hero-list.component.tsfichier. - Modifiez le nom de la classe de composant en HeroListComponent. - Changer le selectorà app-hero-list.

Les sélecteurs ne sont pas requis pour les composants routés car ils sont insérés dynamiquement lors du rendu de la page, mais ils sont utiles pour les identifier et les cibler dans votre arborescence d'éléments HTML.

  • Copiez le hero-detaildossier, les hero.ts, hero.service.tset les mock-heroes.tsfichiers dans le heroessous - dossier.
  • Copiez le message.service.tsdans le src/appdossier.
  • Mettez à jour l'importation du chemin relatif message.servicedans le hero.service.tsfichier.

Ensuite, vous allez mettre à jour les HeroesModulemétadonnées.

  • Importez et ajoutez le HeroDetailComponentet HeroListComponentau declarationstableau dans le HeroesModule.

src/app/heroes/heroes.module.ts

Lorsque vous avez terminé, vous aurez ces fichiers de gestion de héros :



L'exigences de routage des fonctionnalités Hero

La fonction héros a deux composants en interaction, la liste des héros et les détails du héros. La vue liste est autonome; vous y accédez, il obtient une liste de héros et les affiche.

La vue de détail est différente. Il affiche un héros particulier. Il ne peut pas savoir quel héros montrer seul. Cette information doit venir de l'extérieur.

Lorsque l'utilisateur sélectionne un héros dans la liste, l'application doit accéder à la vue détaillée et afficher ce héros. Vous indiquez à la vue détaillée le héros à afficher en incluant l'identifiant du héros sélectionné dans l'URL de la route.

Importez les composants du héros à partir de leurs nouveaux emplacements dans le src/app/heroes/dossier, définissez les deux itinéraires du héros.

Maintenant que vous avez des itinéraires pour le Heroesmodule, enregistrez-les avec le Routervia RouterModule presque comme vous le faisiez dans le AppRoutingModule.

Il y a une petite mais critique différence. Dans le AppRoutingModule, vous avez utilisé la RouterModule.forRootméthode statique pour enregistrer les itinéraires et les fournisseurs de services au niveau de l'application. Dans un module de fonctionnalité, vous utilisez la forChildméthode statique .

Appelez uniquement RouterModule.forRootà la racine AppRoutingModule (ou AppModulesi vous enregistrez les routes d'application de niveau supérieur). Dans tout autre module, vous devez appeler la RouterModule.forChildméthode pour enregistrer des itinéraires supplémentaires.

La mise à jour HeroesRoutingModuleressemble à ceci:

src/app/heroes/heroes-routing.module.ts

Envisagez de donner à chaque module de caractéristiques son propre fichier de configuration de route. Il peut sembler exagéré de bonne heure lorsque les itinéraires sont simples. Mais les itinéraires ont tendance à se complexifier et la cohérence des modèles porte ses fruits avec le temps.

Supprimer l'itinéraires de héros en double

Les itinéraires de héros sont actuellement définis à deux endroits: dans HeroesRoutingModule, par HeroesModuleet dans AppRoutingModule.

Les itinéraires fournis par les modules de fonctions sont combinés ensemble dans les itinéraires de leurs modules importés par le routeur. Cela vous permet de continuer à définir les itinéraires du module de fonctions sans modifier la configuration de l'itinéraire principal.

Supprimez l' HeroListComponentimportation et la /heroesroute de la app-routing.module.ts.

Laissez la route par défaut et les routes génériques! Ce sont des préoccupations au plus haut niveau de l'application elle-même.

src/app/app-routing.module.ts (v2)


Supprimer la déclarations de héros

Supprimez le HeroListComponentdu AppModule, declarationscar il est maintenant fourni par le HeroesModule. Vous pouvez faire évoluer la fonction héros avec plus de composants et différents itinéraires. C'est un avantage clé de créer un module distinct pour chaque domaine de fonctionnalités.

Après ces étapes, le AppModuledevrait ressembler à ceci:

src/app/app.module.ts

L'ordre d'importation des modules est important

Regardez le importstableau de modules . Notez que l' AppRoutingModuleest dernier . Plus important encore, il vient après le HeroesModule.

src/app/app.module.ts (module-imports)

L'ordre de configuration de l'itinéraire est important. Le routeur accepte le premier itinéraire correspondant à un chemin de demande de navigation.

Lorsque toutes les routes étaient dans une AppRoutingModule, vous mettez les routes par défaut et génériques en dernier, après la /heroesroute, afin que le routeur puisse associer une URL à la /heroesroute avant de frapper la route générique et de naviguer vers "Page introuvable".

Les itinéraires ne sont plus dans un fichier. Ils sont répartis sur deux modules AppRoutingModuleet HeroesRoutingModule.

Chaque module de routage augmente la configuration de la route dans l'ordre d'importation. Si vous faites la liste en AppRoutingModulepremier, la route générique sera enregistrée avant les routes du héros. L'itinéraire générique (qui correspond à chaque URL) interceptera la tentative de navigation vers un itinéraire de héros.

Inversez les modules de routage et constatez par vous-même qu'un clic sur le lien des héros donne lieu à une "Page non trouvée". En savoir plus sur l'inspection de la configuration du routeur d'exécution ci-dessous .

Route Parameters

Définition de route avec un paramètre

Retournez à la HeroesRoutingModuleet regardez à nouveau les définitions de route. La route à HeroDetailComponenta une torsion.

src / app / heroes / heroes-routing.module.ts (extrait)

Remarquez le :idjeton dans le chemin. Cela crée un emplacement dans le chemin pour un paramètre de route . Dans ce cas, le routeur insérera le idhéros dans cet emplacement.

Si vous indiquez au routeur de naviguer vers le composant de détail et d'afficher "Magneta", vous vous attendez à ce qu'un identifiant de héros apparaisse dans l'URL du navigateur, comme suit:


Si un utilisateur entre cette URL dans la barre d'adresse du navigateur, le routeur doit reconnaître le modèle et accéder à la même vue détaillée "Magneta".

Remarque : L'incorporation du jeton de paramètre d'itinéraire :id, dans le chemin de définition d'itinéraire est un bon choix pour ce scénario, car elle idest requise par le HeroDetailComponentet parce que la valeur 15du chemin distingue clairement l'itinéraire de "Magneta" d'un itinéraire pour un autre héros.

Définition des paramètres de l'itinéraire dans le affichage de liste

Après avoir navigué vers le HeroDetailComponent, vous vous attendez à voir les détails du héros sélectionné. Vous avez besoin de deux informations: le chemin de routage vers le composant et celui du héros id.

En conséquence, le tableau de paramètres de liaison comporte deux éléments: le chemin de routage et un paramètre de route qui spécifie le idhéros sélectionné.

src / app / heroes / hero-list / hero-list.component.ts (tableau de paramètres de liens)

Le routeur compose l'URL de destination du tableau comme ceci: localhost:4200/hero/15.

Comment la cible en HeroDetailComponentapprend-elle id? Ne pas analyser l'URL. Laissez le routeur le faire. Le routeur extrait le paramètre route ( id:15) de l'URL et le fournit au HeroDetailComponentvia le ActivatedRouteservice.


Route activée en action

Importez le Router, ActivatedRouteet les ParamMapjetons à partir du package du routeur.

src / app / heroes / hero-detail / hero-detail.component.ts (itinéraire activé)

Importez l' switchMapopérateur car vous en aurez besoin ultérieurement pour traiter les Observableparamètres de l' itinéraire.

src / app / heroes / hero-detail / hero-detail.component.ts (importation de l'opérateur switchMap)

Comme d'habitude, vous écrivez un constructeur qui demande à Angular d'injecter les services requis par le composant et de les référencer en tant que variables privées.

src / app / heroes / hero-detail / hero-detail.component.ts (constructeur)

Plus tard, dans la ngOnInitméthode, vous utilisez le ActivatedRouteservice pour récupérer les paramètres de la route, extraire le héros iddes paramètres et récupérer le héros à afficher.

src / app / heroes / hero-detail / hero-detail.component.ts (ngOnInit)

Le paramMaptraitement est un peu délicat. Lorsque la carte change, vous définissez get() le idparamètre à partir des paramètres modifiés.

Ensuite, vous dites à la personne HeroServiced'aller chercher le héros avec cela idet de retourner le résultat de la HeroServicedemande.

Vous pourriez penser à utiliser l' mapopérateur RxJS . Mais les HeroServiceretours un Observable ‹Hero›. Donc, vous mettez à plat Observablel' switchMapopérateur avec.

L'opérateur switchMap annule également les demandes précédentes en vol. Si l'utilisateur re-navigue vers cette route avec une nouvelle idalors que le HeroServicerécupère encore l'ancienne id, switchMaprejette cette ancienne requête et renvoie le héros pour la nouvelle id.

L'observable Subscriptionsera géré par le AsyncPipeet la heropropriété du composant sera (re) définie avec le héros récupéré.


ParamMap API

L'API ParamMap est inspirée de l'interface URLSearchParams. Il fournit des méthodes pour gérer l'accès aux paramètres pour les paramètres de route (paramMap) et les paramètres de requête ( queryParamMap).

Membre Description
has(name) Retourne truesi le nom du paramètre est dans la carte des paramètres.
get(name) Renvoie la valeur du nom du paramètre (a string) si elle est présente ou nullsi le nom du paramètre ne figure pas dans la carte. Retourne le premier élément si la valeur du paramètre est en réalité un tableau de valeurs.
getAll(name) Retourne une string arrayvaleur de nom de paramètre si elle est trouvée ou vide arraysi la valeur de nom de paramètre n'est pas dans la carte. Utiliser getAlllorsqu'un seul paramètre peut avoir plusieurs valeurs.
keys Renvoie un string arraydes noms de paramètres de la carte.


Observable paramMap and component reuse

Dans cet exemple, vous récupérez la carte de paramètres de route depuis un fichier Observable. Cela implique que la carte de paramètres de route peut changer pendant la durée de vie de ce composant.

Ils pourraient. Par défaut, le routeur réutilise une instance de composant lorsqu'il navigue dans le même type de composant sans visiter un autre composant au préalable. Les paramètres de route peuvent changer à chaque fois.

Supposons qu'une barre de navigation du composant parent comporte des boutons "Suivant" et "Précédent" qui permettent de faire défiler la liste des héros. Chaque clic a navigué impérativement vers le HeroDetailComponentavec le suivant ou le précédent id.

Vous ne voulez pas que le routeur supprime l' HeroDetailComponentinstance actuelle du DOM uniquement pour la recréer ultérieurement id. Cela pourrait être visiblement choquant. Mieux vaut simplement réutiliser la même instance de composant et mettre à jour le paramètre.

Malheureusement, ngOnInitn'est appelée qu'une fois par instanciation de composant. Vous avez besoin d'un moyen de détecter le moment où les paramètres de route changent dans la même instance. La paramMappropriété observable gère cela magnifiquement.

Lorsque vous vous abonnez à un observable dans un composant, vous vous arrêtez presque toujours pour vous désabonner lorsque le composant est détruit.

Il y a quelques observables exceptionnels où ce n'est pas nécessaire. Les ActivatedRouteobservables font partie des exceptions.

Le ActivatedRouteet ses observables sont isolés du Routerlui - même. Le Routerdétruit un composant routé quand il n'est plus nécessaire et l'injecté ActivatedRoutemeurt avec lui.

N'hésitez pas à vous désinscrire quand même. C'est inoffensif et jamais une mauvaise pratique.


Instantané : le alternatif non observable

Cette application ne réutilisera pas le HeroDetailComponent. L'utilisateur revient toujours à la liste des héros pour sélectionner un autre héros à afficher. Il est impossible de naviguer d'un détail de héros à un autre sans consulter le composant de liste situé entre les deux. Par conséquent, le routeur crée une nouvelle HeroDetailComponentinstance à chaque fois.

Lorsque vous savez avec certitude qu'une HeroDetailComponentinstance ne sera jamais, jamais, jamais réutilisée, vous pouvez simplifier le code avec l' instantané .

Le route.snapshotfournit la valeur initiale de la carte de paramètres de route. Vous pouvez accéder directement aux paramètres sans souscrire ni ajouter d'opérateurs observables. C'est beaucoup plus simple d'écrire et de lire:

N'oubliez pas que vous n'obtenez que la valeur initiale de la mappe de paramètres avec cette technique. Respectez l' paramMapapproche observable s'il existe une chance que le routeur réutilise le composant. Cet échantillon reste avec la paramMapstratégie observable au cas où.
src / app / heroes / hero-detail / hero-detail.component.ts (instantané ngOnInit)


Revenir à la liste

Le HeroDetailComponentbouton possède un bouton "Retour" relié à sa gotoHeroesméthode qui permet de revenir impérativement à la page HeroListComponent.

La navigateméthode de routeur utilise le même tableau de paramètres de liaison à élément unique que vous pouvez lier à une directive. Il détient le chemin vers le :[routerLink]HeroListComponent

src / app / heroes / hero-detail / hero-detail.component.ts (extrait)

Utilisez les paramètres de route pour spécifier une valeur de paramètre requise dans l'URL de route, comme vous le faites lorsque vous accédez HeroDetailComponentà pour afficher le héros avec l' identifiant 15:

Paramètres de route: Obligatoire ou facultatif ?

Vous pouvez également ajouter des informations facultatives à une demande d'itinéraire. Par exemple, lorsque vous revenez à la liste hero-detail.component.ts à partir de la vue détaillée du héros, il serait bien que le héros visualisé soit présélectionné dans la liste.



Vous allez implémenter cette fonctionnalité dans un instant en incluant le héros visualisé id dans l'URL comme paramètre facultatif lors du retour depuis le fichier HeroDetailComponent.

Les informations facultatives prennent d'autres formes. Les critères de recherche sont souvent mal structurés, par exemple name='wind*'. Plusieurs valeurs sont communes after='12/31/2015' & before='1/1/2017'- dans aucun ordre particulier before='1/1/2017' & after='12/31/2015'- dans une variété de formats - during='currentYear'.

Ces types de paramètres ne rentrent pas facilement dans un chemin d' URL. Même si vous pouviez définir un schéma de jeton d'URL approprié, cela compliquerait grandement la correspondance de modèle requise pour traduire une URL entrante en une route nommée.

Les paramètres facultatifs sont le véhicule idéal pour transmettre des informations arbitrairement complexes pendant la navigation. Les paramètres facultatifs n'interviennent pas dans la correspondance des modèles et offrent une souplesse d'expression.

Le routeur prend en charge la navigation avec des paramètres facultatifs ainsi que les paramètres de route requis. Définissez des paramètres facultatifs dans un objet distinct après avoir défini les paramètres de routage requis.

En général, préférez un paramètre de route requis lorsque la valeur est obligatoire (par exemple, si nécessaire pour distinguer un chemin de route d'un autre); préférez un paramètre facultatif lorsque la valeur est facultative, complexe et / ou multivariée.

Liste des héros: sélection éventuelle d'un héros

Lors de la navigation, HeroDetailComponentvous avez spécifié le paramètre requis id du héros à modifier dans le paramètre route et vous en avez fait le deuxième élément du tableau des paramètres de liaison.

src / app / heroes / hero-list / hero-list.component.ts (tableau de paramètres de liens)

Le routeur a incorporé la idvaleur dans l'URL de navigation car vous l'aviez définie en tant que paramètre d'itinéraire avec un :idjeton d'espace réservé dans l'itinéraire path:

src / app / heroes / heroes-routing.module.ts (hero-detail-route)

Lorsque l'utilisateur clique sur le bouton Précédent, il HeroDetailComponentconstruit un autre tableau de paramètres de liens qu'il utilise pour revenir au fichier HeroListComponent.

src / app / heroes / hero-detail / hero-detail.component.ts (gotoHeroes)

Il n'existe pas de paramètre de route dans ce tableau car vous n'avez aucune raison d'envoyer des informations à HeroListComponent.

Maintenant vous avez une raison. Vous souhaitez envoyer l'identifiant du héros actuel avec la demande de navigation afin qu'il HeroListComponentpuisse le surligner dans sa liste. C'est une fonctionnalité intéressante. la liste s'affichera parfaitement bien sans elle.

Envoyez le idavec un objet contenant un paramètre facultatif id . à des fins de démonstration, il existe un paramètre indésirable supplémentaire (foo) dans l'objet qu'il HeroListComponentdoit ignorer. Voici la déclaration de navigation révisée:

src / app / heroes / hero-detail / hero-detail.component.ts (aller aux héros)

L'application fonctionne toujours. En cliquant sur "retour" revient à la vue de la liste des héros.

Regardez la barre d'adresse du navigateur.

Cela devrait ressembler à ceci, selon l'endroit où vous le lancez:

La idvaleur apparaît dans l'URL sous la forme ( ;id=15;foo=foo), pas dans le chemin de l'URL. Le chemin pour la route "Heroes" n'a pas de :idjeton.

Les paramètres de route facultatifs ne sont pas séparés par "?" et "&" comme ils seraient dans la chaîne de requête d'URL. Ils sont séparés par des points-virgules ";" Il s'agit d' une notation d' URL matricielle , quelque chose que vous n'avez peut-être pas vu auparavant.

La notation Matrix URL est une idée introduite dans une proposition de 1996 du fondateur du Web, Tim Berners-Lee.

Bien que la notation matricielle ne soit jamais entrée dans la norme HTML, elle est légale et est devenue populaire parmi les systèmes de routage de navigateur pour isoler les paramètres appartenant aux routes parent et enfant. Le routeur est un tel système et prend en charge la notation matricielle sur les navigateurs.

La syntaxe peut sembler étrange pour vous, mais il est peu probable que les utilisateurs le remarquent, tant que l'URL peut être envoyée par courrier électronique et collée dans une barre d'adresse du navigateur comme celle-ci le peut.


Paramètres de route dans le service ActivatedRoute

La liste des héros est inchangée. Aucune rangée de héros n'est en surbrillance.

le exemple live / exemple de téléchargement ne mettre en évidence la ligne sélectionnée car elle démontre l'état final de l'application qui comprend les étapes que vous êtes sur les couvrir. Pour le moment, ce guide décrit la situation avant ces étapes.

Le HeroListComponentn'attend aucun paramètre et ne sait pas quoi en faire. Tu peux changer ça.

Auparavant, lors de la navigation de la HeroListComponentà la HeroDetailComponent, vous vous êtes abonné à la mappe de paramètres d'itinéraire Observableet vous la mettez à la disposition HeroDetailComponent du ActivatedRouteservice. Vous avez injecté ce service dans le constructeur de HeroDetailComponent.

Cette fois -ci vous serez naviguer dans la direction opposée, de l' HeroDetailComponentau HeroListComponent.

Vous devez d'abord étendre la déclaration d'importation du routeur pour inclure le ActivatedRoutesymbole de service:

src / app / heroes / hero-list / hero-list.component.ts (import)

Importez l' switchMapopérateur pour effectuer une opération sur la Observablemappe de paramètres de route.

src / app / heroes / hero-list / hero-list.component.ts (importations rxjs)

Ensuite, vous injectez le ActivatedRoutedans le HeroListComponentconstructeur.

src / app / heroes / hero-list / hero-list.component.ts (constructeur et ngOnInit)

La ActivatedRoute.paramMappropriété est une Observablecarte de paramètres de route. Le paramMapémet une nouvelle carte de valeurs à inclure id lorsque l'utilisateur accède au composant. En ngOnInitvous abonnant à ces valeurs, définissez le selectedIdet obtenez les héros. Mettez à jour le modèle avec une liaison de classe . La liaison ajoute la selectedclasse CSS lorsque la comparaison est renvoyée trueet la supprime quand false. Recherchez-le dans la ‹li› balise répétée, comme indiqué ici:
src / app / heroes / hero-list / hero-list.component.html

Ajoutez des styles à appliquer lorsque l'élément de liste est sélectionné.

src / app / heroes / hero-list / hero-list.component.css

Lorsque l'utilisateur navigue de la liste des héros au héros "Magneta" et au dos, "Magneta" apparaît sélectionné:



Le fooparamètre optionnel route est inoffensif et continue d'être ignoré.

Jalon 3 : Ajout d'animations routables

Ajout d'animations au composant routé.

Le module de fonctionnalités des héros est presque terminé, mais qu'est-ce qu'une fonctionnalité sans transitions douces?

Cette section vous montre comment ajouter des animations au HeroDetailComponent.

Commencez par importer le BrowserAnimationsModuleet ajoutez-le au importstableau:

src / app / app.module.ts (module d'animation)

Ensuite, ajoutez un dataobjet aux routes pour HeroListComponentet HeroDetailComponent. Les transitions sont basées sur stateset vous utiliserez les animationdonnées de la route pour fournir une animation nommée statepour les transitions.

src / app / heroes / heroes-routing.module.ts (données d'animation)

Créez un animations.tsfichier dans le src/app/dossier racine . Le contenu ressemble à ceci:

src / app / animations.ts (extrait)

Ce fichier fait ce qui suit :

  • Importe les symboles d'animation qui construisent les déclencheurs d'animation, contrôlent l'état et gèrent les transitions entre les états.
  • Exporte un slideInAnimationensemble nommé constant vers un déclencheur d'animation nommé routeAnimation;
  • Définit une transition lors du basculement entre les routes heroeset heropour ramener le composant de gauche à l'écran lorsqu'il entre dans la vue de l'application ( :enter), l'autre pour animer le composant à droite en quittant la vue de l'application ( :leave).
Vous pouvez également créer plus de transitions pour d'autres itinéraires. Ce déclencheur est suffisant pour le jalon actuel.

De retour dans le AppComponent, importez le RouterOutletjeton du @angular/routerpackage et le slideInDownAnimationde './animations.ts.

Ajoutez un animationstableau aux métadonnées contenant le fichier .@ComponentslideInDownAnimation

src / app / app.component.ts (animations)

Pour utiliser les animations routables, vous devez envelopper l' RouterOutletintérieur d'un élément. Vous utiliserez le @routeAnimationdéclencheur et le lierez à l'élément.

Pour les @routeAnimationtransitions vers les états désactivés, vous devez le fournir avec datale ActivatedRoute. Le RouterOutletest exposé en tant que outletvariable de modèle, de sorte que vous liez une référence à la sortie du routeur. Une variable de routerOutletest un choix idéal.

src / app / app.component.html (sortie du routeur)

La @routeAnimationpropriété est liée à getAnimationDataavec la routerOutletréférence fournie. Vous devez donc définir cette fonction dans le fichier AppComponent. La getAnimationDatafonction retourne la propriété animation à partir de datafourni par ActivatedRoute. La animationpropriété correspond aux transitionnoms que vous avez utilisés dans le slideDownAnimationdéfini dans animations.ts.

src / app / app.component.ts (prise de routeur)

Lors de la commutation entre les deux voies, la HeroDetailComponentet HeroListComponentfacilitera de la gauche lorsqu'ils sont acheminés vers et va glisser vers la droite lors de la navigation à une distance.