Replay

Apprendre Angular en 1h

Je me donne un objectif: vous faire découvrir et apprendre Angular en 1 heure: composant, syntaxe dans les templates, les directives, les signaux, les routeurs, les services, l'injection de dépendances, les observables et les requêtes HTTP. Le nécessaire pour faire une application Angular !.

Skip to content

Vous souhaitez recevoir de l'aide sur ce sujet ? rejoignez la communauté Angular.fr sur Discord.

Créer un simple routeur

Dans le module, nous définissons les chemins pour les composants dans app.routes.ts :

ts
import { RouterModule, Routes } from '@angular/router';

import {OtherComponent} from './other.component';
import {MainComponent} from './main.component';

export const routes: Routes = [
  { path: '', component: MainComponent },
  { path: 'other', component: OtherComponent }
];

On admet que nous avons 2 composants : MainComponent et OtherComponent. Nous créons donc un tableau définissant les différentes routes.

Chargeons le provider du routeur

Dans le fichier app.config.ts, nous chargeons le provider du routeur :

ts
import { ApplicationConfig } from '@angular/core';
import { provideRouter } from '@angular/router';
import { routes } from './app.routes';

export const appConfig: ApplicationConfig = {
    providers: [
        provideRouter(routes)
    ]
};

provideRouter prend en paramètre le tableau des routes définies précédemment. Il permet de charger le routeur dans l'application.

Imaginons un menu de restaurant où vous avez différentes sections (entrées, plats, desserts). Pour naviguer entre ces sections, vous utilisez des onglets. C'est exactement le même principe avec RouterLink dans Angular !

ts
import { Component } from '@angular/core';
import { RouterOutlet, RouterLink } from '@angular/router';

@Component({
  selector: 'app-root',
  standalone: true,
  imports: [RouterOutlet, RouterLink],
  template: `
    <ul>
      <li><a routerLink="/">main</a></li>
      <li><a routerLink="/other">other</a></li>
    </ul>
    <router-outlet />
  `
})
export class AppComponent {
}

RouterLink vs href

Utilisez toujours routerLink au lieu de href pour la navigation interne de votre application. routerLink empêche le rechargement complet de la page et offre une meilleure expérience utilisateur.

Mise en évidence avec RouterLinkActive

Reprenons notre analogie du menu de restaurant. Quand vous êtes dans la section "desserts", vous voulez que l'onglet "desserts" soit mis en évidence pour que les clients sachent où ils se trouvent. C'est exactement ce que fait RouterLinkActive !

ts
import { Component } from '@angular/core';
import { RouterOutlet, RouterLink, RouterLinkActive } from '@angular/router';

@Component({
  selector: 'app-root',
  standalone: true,
  imports: [RouterOutlet, RouterLink, RouterLinkActive],
  template: `
    <ul>
      <li><a routerLink="/" routerLinkActive="active" [routerLinkActiveOptions]="{exact: true}">main</a></li>
      <li><a routerLink="/other" routerLinkActive="active">other</a></li>
    </ul>
    <router-outlet />
  `,
  styles: `
    .active {
      color: red;
      font-weight: bold;
    }
  `
})
export class AppComponent {
}

Exact Matching

Pour la route racine /, utilisez [routerLinkActiveOptions]="{exact: true}". Sans cette option, le lien serait toujours actif car tous les chemins commencent par /.

Multiple Classes

Vous pouvez ajouter plusieurs classes CSS avec RouterLinkActive :

html
<a routerLink="/" routerLinkActive="active highlighted selected">main</a>

Configuration avancée avec RouterLinkActiveOptions

Imaginons maintenant que dans notre menu de restaurant, nous voulons gérer différemment l'affichage des sous-sections. Par exemple, nous voulons que "Desserts" soit mis en évidence uniquement quand nous sommes exactement dans cette section, et pas dans ses sous-sections comme "Gâteaux" ou "Glaces". C'est là que RouterLinkActiveOptions entre en jeu !

ts
@Component({
  template: `
    <nav>
      <a routerLink="/desserts" 
         routerLinkActive="active" 
         [routerLinkActiveOptions]="{
           exact: true,
           queryParams: 'exact',
           fragment: 'preserve'
         }">
        Desserts
      </a>
    </nav>
  `
})

RouterLinkActiveOptions propose trois options principales :

ts
// L'option 'exact' assure que la classe active est appliquée 
// uniquement si l'URL correspond exactement
[routerLinkActiveOptions]="{ exact: true }"
ts
// L'option 'queryParams' gère la correspondance des paramètres de requête
[routerLinkActiveOptions]="{ queryParams: 'exact' }" // correspond exactement
[routerLinkActiveOptions]="{ queryParams: 'ignored' }" // ignore les paramètres
[routerLinkActiveOptions]="{ queryParams: 'subset' }" // correspond si sous-ensemble
ts
// L'option 'fragment' gère la correspondance du fragment d'URL
[routerLinkActiveOptions]="{ fragment: 'exact' }" // correspond exactement
[routerLinkActiveOptions]="{ fragment: 'ignored' }" // ignore le fragment

Cas d'utilisation

  • Utilisez exact: true pour les routes racines ou quand vous voulez une correspondance exacte
  • Utilisez queryParams: 'exact' pour les pages de recherche ou de filtrage
  • Utilisez fragment: 'preserve' pour les pages avec des ancres de navigation

Attention aux routes imbriquées

Sans exact: true, un lien vers /desserts sera considéré comme actif même si l'URL actuelle est /desserts/gateaux. Assurez-vous de bien comprendre la hiérarchie de vos routes avant de configurer RouterLinkActiveOptions.

Exemple complet avec différentes configurations :

ts
@Component({
  template: `
    <nav>
      <!-- Correspondance exacte de l'URL -->
      <a routerLink="/menu" 
         routerLinkActive="active" 
         [routerLinkActiveOptions]="{ exact: true }">
        Menu
      </a>

      <!-- Correspondance exacte avec paramètres de requête -->
      <a routerLink="/plats" 
         [queryParams]="{ categorie: 'pizza' }"
         routerLinkActive="active" 
         [routerLinkActiveOptions]="{ 
           exact: true,
           queryParams: 'exact'
         }">
        Pizzas
      </a>

      <!-- Ignore les fragments d'URL -->
      <a routerLink="/contact" 
         routerLinkActive="active" 
         [routerLinkActiveOptions]="{ 
           exact: true,
           fragment: 'ignored'
         }">
        Contact
      </a>
    </nav>
  `
})