Intégrer la page de détails dans l'application

Cette leçon du tutoriel montre comment connecter la page de détails à votre application.

Important : Nous vous recommandons d'utiliser votre environnement local pour apprendre le routing.

Ce que vous allez apprendre

À la fin de cette leçon, votre application prendra en charge le routing vers la page de détails.

Aperçu conceptuel du routing avec des paramètres de route

Chaque logement possède des détails spécifiques qui doivent être affichés lorsqu'un utilisateur navigue vers la page de détails de cet élément. Pour y parvenir, vous devrez utiliser des paramètres de route.

Les paramètres de route vous permettent d'inclure des informations dynamiques dans l'URL de votre route. Pour identifier le logement sur lequel un utilisateur a cliqué, vous utiliserez la propriété id du type HousingLocation.

  1. Dans la leçon 10, vous avez ajouté une seconde route dans src/app/routes.ts, qui inclut un segment particulier identifiant le paramètre de route, id :

    'details/:id'

    Ici, :id est dynamique et changera selon la manière dont la route est demandée par le code.

    1. Dans src/app/housing-location/housing-location.ts, ajoutez une balise d'ancre à l'élément section et incluez la directive routerLink :

      Ajouter une ancre avec une directive routerLink dans housing-location.ts

      import {Component, input} from '@angular/core';
      import {HousingLocationInfo} from '../housinglocation';
      import {RouterLink} from '@angular/router';
      
      @Component({
        selector: 'app-housing-location',
        imports: [RouterLink],
        template: `
          <section class="listing">
            <img
              class="listing-photo"
              [src]="housingLocation().photo"
              alt="Exterior photo of {{ housingLocation().name }}"
              crossorigin
            />
            <h2 class="listing-heading">{{ housingLocation().name }}</h2>
            <p class="listing-location">{{ housingLocation().city }}, {{ housingLocation().state }}</p>
            <a [routerLink]="['/details', housingLocation().id]">Learn More</a>
          </section>
        `,
        styleUrls: ['./housing-location.css'],
      })
      export class HousingLocation {
        housingLocation = input.required<HousingLocationInfo>();
      }

      La directive routerLink permet au router d'Angular de créer des liens dynamiques dans l'application. La valeur affectée à routerLink est un tableau de deux entrées : la partie statique du chemin et les données dynamiques.

      Pour que routerLink fonctionne dans le template, ajoutez un import au niveau du fichier de RouterLink depuis '@angular/router', puis modifiez le tableau imports du composant pour y inclure RouterLink.

    2. À ce stade, vous pouvez vérifier que le routing fonctionne dans votre application. Dans le navigateur, actualisez la page d'accueil et cliquez sur le bouton « Learn More » d'un logement.

      page de détails affichant le texte 'details works!'
  2. Récupérer les paramètres de route

    Dans cette étape, vous allez récupérer le paramètre de route dans Details. Actuellement, l'application affiche details works!. Vous allez ensuite modifier le code pour afficher la valeur id transmise via les paramètres de route.

    1. Dans src/app/details/details.ts, modifiez le template pour importer les fonctions, classes et services dont vous aurez besoin dans Details :

      Modifier les imports au niveau du fichier

      import {Component, inject} from '@angular/core';
      import {ActivatedRoute} from '@angular/router';
      import {HousingService} from '../housing.service';
      import {HousingLocationInfo} from '../housinglocation';
      
      @Component({
        selector: 'app-details',
        template: `
          <article>
            <img
              class="listing-photo"
              [src]="housingLocation?.photo"
              alt="Exterior photo of {{ housingLocation?.name }}"
              crossorigin
            />
            <section class="listing-description">
              <h2 class="listing-heading">{{ housingLocation?.name }}</h2>
              <p class="listing-location">{{ housingLocation?.city }}, {{ housingLocation?.state }}</p>
            </section>
            <section class="listing-features">
              <h2 class="section-heading">About this housing location</h2>
              <ul>
                <li>Units available: {{ housingLocation?.availableUnits }}</li>
                <li>Does this location have wifi: {{ housingLocation?.wifi }}</li>
                <li>Does this location have laundry: {{ housingLocation?.laundry }}</li>
              </ul>
            </section>
          </article>
        `,
        styleUrls: ['./details.css'],
      })
      export class Details {
        route: ActivatedRoute = inject(ActivatedRoute);
        housingService = inject(HousingService);
        housingLocation: HousingLocationInfo | undefined;
      
        constructor() {
          const housingLocationId = Number(this.route.snapshot.params['id']);
          this.housingLocation = this.housingService.getHousingLocationById(housingLocationId);
        }
      }
    2. Modifiez la propriété template du décorateur @Component pour afficher la valeur housingLocationId :

      template: `<p>details works! {{ housingLocationId }}</p>`,
    3. Modifiez le corps de la classe Details avec le code suivant :

      export class Details {
         route: ActivatedRoute = inject(ActivatedRoute);
         housingLocationId = -1;
         constructor() {
         this.housingLocationId = Number(this.route.snapshot.params['id']);
         }
      }

      Ce code donne à Details accès à la fonctionnalité ActivatedRoute du router, qui vous permet d'accéder aux données de la route courante. Dans le constructor, le code convertit le paramètre id récupéré depuis la route d'une chaîne en nombre.

    4. Enregistrez toutes les modifications.

    5. Dans le navigateur, cliquez sur l'un des liens « Learn More » d'un logement et vérifiez que la valeur numérique affichée sur la page correspond à la propriété id de ce logement dans les données.

  3. Personnaliser Details

    Maintenant que le routing fonctionne correctement dans l'application, c'est le bon moment pour modifier le template de Details afin d'afficher les données spécifiques du logement correspondant au paramètre de route.

    Pour accéder aux données, vous allez ajouter un appel à HousingService.

    1. Modifiez le code du template pour qu'il corresponde au code suivant :

      Modifier le template de Details dans src/app/details/details.ts

      import {Component, inject} from '@angular/core';
      import {ActivatedRoute} from '@angular/router';
      import {HousingService} from '../housing.service';
      import {HousingLocationInfo} from '../housinglocation';
      
      @Component({
        selector: 'app-details',
        template: `
          <article>
            <img
              class="listing-photo"
              [src]="housingLocation?.photo"
              alt="Exterior photo of {{ housingLocation?.name }}"
              crossorigin
            />
            <section class="listing-description">
              <h2 class="listing-heading">{{ housingLocation?.name }}</h2>
              <p class="listing-location">{{ housingLocation?.city }}, {{ housingLocation?.state }}</p>
            </section>
            <section class="listing-features">
              <h2 class="section-heading">About this housing location</h2>
              <ul>
                <li>Units available: {{ housingLocation?.availableUnits }}</li>
                <li>Does this location have wifi: {{ housingLocation?.wifi }}</li>
                <li>Does this location have laundry: {{ housingLocation?.laundry }}</li>
              </ul>
            </section>
          </article>
        `,
        styleUrls: ['./details.css'],
      })
      export class Details {
        route: ActivatedRoute = inject(ActivatedRoute);
        housingService = inject(HousingService);
        housingLocation: HousingLocationInfo | undefined;
      
        constructor() {
          const housingLocationId = Number(this.route.snapshot.params['id']);
          this.housingLocation = this.housingService.getHousingLocationById(housingLocationId);
        }
      }

      Remarquez que les propriétés de housingLocation sont accédées avec l'opérateur de chaînage optionnel ?. Cela garantit que l'application ne plante pas si la valeur de housingLocation est null ou undefined.

    2. Modifiez le corps de la classe Details pour qu'il corresponde au code suivant :

      Modifier la classe Details dans src/app/details/details.ts

      import {Component, inject} from '@angular/core';
      import {ActivatedRoute} from '@angular/router';
      import {HousingService} from '../housing.service';
      import {HousingLocationInfo} from '../housinglocation';
      
      @Component({
        selector: 'app-details',
        template: `
          <article>
            <img
              class="listing-photo"
              [src]="housingLocation?.photo"
              alt="Exterior photo of {{ housingLocation?.name }}"
              crossorigin
            />
            <section class="listing-description">
              <h2 class="listing-heading">{{ housingLocation?.name }}</h2>
              <p class="listing-location">{{ housingLocation?.city }}, {{ housingLocation?.state }}</p>
            </section>
            <section class="listing-features">
              <h2 class="section-heading">About this housing location</h2>
              <ul>
                <li>Units available: {{ housingLocation?.availableUnits }}</li>
                <li>Does this location have wifi: {{ housingLocation?.wifi }}</li>
                <li>Does this location have laundry: {{ housingLocation?.laundry }}</li>
              </ul>
            </section>
          </article>
        `,
        styleUrls: ['./details.css'],
      })
      export class Details {
        route: ActivatedRoute = inject(ActivatedRoute);
        housingService = inject(HousingService);
        housingLocation: HousingLocationInfo | undefined;
      
        constructor() {
          const housingLocationId = Number(this.route.snapshot.params['id']);
          this.housingLocation = this.housingService.getHousingLocationById(housingLocationId);
        }
      }

      Le composant dispose maintenant du code pour afficher les bonnes informations selon le logement sélectionné. Le constructor inclut désormais un appel à HousingService pour passer le paramètre de route en argument à la fonction getHousingLocationById du service.

    3. Copiez les styles suivants dans le fichier src/app/details/details.css :

      Ajouter les styles de Details

      .listing-photo {
        height: 600px;
        width: 50%;
        object-fit: cover;
        border-radius: 30px;
        float: right;
      }
      
      .listing-heading {
        font-size: 48pt;
        font-weight: bold;
        margin-bottom: 15px;
      }
      
      .listing-location::before {
        content: url('/public/location-pin.svg') / '';
      }
      
      .listing-location {
        font-size: 24pt;
        margin-bottom: 15px;
      }
      
      .listing-features > .section-heading {
        color: var(--secondary-color);
        font-size: 24pt;
        margin-bottom: 15px;
      }
      
      .listing-features {
        margin-bottom: 20px;
      }
      
      .listing-features li {
        font-size: 14pt;
      }
      
      li {
        list-style-type: none;
      }
      
      .listing-apply .section-heading {
        font-size: 18pt;
        margin-bottom: 15px;
      }
      
      label,
      input {
        display: block;
      }
      label {
        color: var(--secondary-color);
        font-weight: bold;
        text-transform: uppercase;
        font-size: 12pt;
      }
      input {
        font-size: 16pt;
        margin-bottom: 15px;
        padding: 10px;
        width: 400px;
        border-top: none;
        border-right: none;
        border-left: none;
        border-bottom: solid 0.3px;
      }
      @media (max-width: 1024px) {
        .listing-photo {
          width: 100%;
          height: 400px;
        }
      }

      et enregistrez vos modifications

    4. Dans Details, utilisez le fichier details.css que vous venez de créer comme source des styles :

      Modifier details.ts pour utiliser le fichier css créé

      import {Component, inject} from '@angular/core';
      import {ActivatedRoute} from '@angular/router';
      import {HousingService} from '../housing.service';
      import {HousingLocationInfo} from '../housinglocation';
      
      @Component({
        selector: 'app-details',
        template: `
          <article>
            <img
              class="listing-photo"
              [src]="housingLocation?.photo"
              alt="Exterior photo of {{ housingLocation?.name }}"
              crossorigin
            />
            <section class="listing-description">
              <h2 class="listing-heading">{{ housingLocation?.name }}</h2>
              <p class="listing-location">{{ housingLocation?.city }}, {{ housingLocation?.state }}</p>
            </section>
            <section class="listing-features">
              <h2 class="section-heading">About this housing location</h2>
              <ul>
                <li>Units available: {{ housingLocation?.availableUnits }}</li>
                <li>Does this location have wifi: {{ housingLocation?.wifi }}</li>
                <li>Does this location have laundry: {{ housingLocation?.laundry }}</li>
              </ul>
            </section>
          </article>
        `,
        styleUrls: ['./details.css'],
      })
      export class Details {
        route: ActivatedRoute = inject(ActivatedRoute);
        housingService = inject(HousingService);
        housingLocation: HousingLocationInfo | undefined;
      
        constructor() {
          const housingLocationId = Number(this.route.snapshot.params['id']);
          this.housingLocation = this.housingService.getHousingLocationById(housingLocationId);
        }
      }
    5. Dans le navigateur, actualisez la page et vérifiez que, lorsque vous cliquez sur le lien « Learn More » d'un logement donné, la page de détails affiche les bonnes informations selon les données de l'élément sélectionné.

    Page de détails présentant les informations du logement
  4. Vérifier la navigation dans Home

    Dans une leçon précédente, vous avez modifié le template de App pour y inclure un routerLink. Ce code a permis à votre application de revenir à Home chaque fois que l'on clique sur le logo.

    1. Vérifiez que votre code correspond à ce qui suit :

      Vérifier le routerLink dans app.ts

      import {Component} from '@angular/core';
      import {Home} from './home/home';
      import {RouterLink, RouterOutlet} from '@angular/router';
      
      @Component({
        selector: 'app-root',
        imports: [Home, RouterLink, RouterOutlet],
        template: `
          <main>
            <a [routerLink]="['/']">
              <header class="brand-name">
                <img class="brand-logo" src="/public/logo.svg" alt="logo" aria-hidden="true" />
              </header>
            </a>
            <section class="content">
              <router-outlet />
            </section>
          </main>
        `,
        styleUrls: ['./app.css'],
      })
      export class App {
        title = 'homes';
      }

      Votre code devrait déjà être à jour, mais vérifiez-le pour en être sûr.

Résumé : Dans cette leçon, vous avez ajouté du routing pour afficher les pages de détails.

Vous savez maintenant :

  • utiliser des paramètres de route pour transmettre des données à une route
  • utiliser la directive routerLink pour créer une route à partir de données dynamiques
  • utiliser un paramètre de route pour récupérer des données depuis HousingService afin d'afficher les informations d'un logement précis.

Excellent travail jusqu'ici.

Pour plus d'informations sur les sujets abordés dans cette leçon, consultez :