Appearance
Les fragments dans le routing Angular
Les fragments permettent de naviguer vers une section spécifique d'une page, similaire aux ancres HTML. C'est particulièrement utile pour les longues pages où l'on souhaite diriger l'utilisateur vers un contenu précis.
D'abord, définissons une section dans notre template avec un id :
ts
import { Component } from '@angular/core';
import { User } from './user.ts';
@Component({
standalone: true,
selector: 'app-user',
template: `
<div class="user-container">
<h1>Liste des utilisateurs</h1>
<!-- Section avec un id pour le fragment -->
<div id="user-list">
@for (user of users; track user.id) {
<div class="user-card">
{{ user.name }}
</div>
}
</div>
</div>
`
})
export class UserComponent {
users: User[] = [];
}
ts
import { Routes } from '@angular/router';
import { UserComponent } from './user.component';
export const routes: Routes = [
{
path: 'users',
component: UserComponent
}
];
ts
export interface User {
id: number;
name: string;
username?: string;
email: string;
address?: {
street: string;
suite: string;
city: string;
zipcode: string;
geo: {
lat: string;
lng: string;
}
};
phone?: string;
website?: string;
company?: {
name: string;
catchPhrase: string;
bs: string;
};
}
La route '/users' qui affiche le UserComponent où nous utilisons les fragments
Navigation avec fragments
Il existe plusieurs façons d'utiliser les fragments :
Via routerLink
ts
import { Component } from '@angular/core';
import { RouterLink, RouterOutlet } from '@angular/router';
@Component({
standalone: true,
selector: 'app-root',
imports: [RouterLink, RouterOutlet],
template: `
<nav class="navigation">
<button
routerLink="/users"
fragment="user-list"
>
Voir la liste des utilisateurs
</button>
</nav>
<main>
<router-outlet></router-outlet>
</main>
`,
})
export class AppComponent {}
Via Router Service
ts
import { Component, inject } from '@angular/core';
import { Router } from '@angular/router';
@Component({
standalone: true,
selector: 'app-home',
template: `
<button (click)="navigateToUserList()">Voir la liste des utilisateurs</button>
`,
})
export class HomeComponent {
private router = inject(Router);
navigateToUserList() {
this.router.navigate(['/users'], { fragment: 'user-list' });
}
}
Scroll automatique
Par défaut, Angular scrollera automatiquement vers l'élément correspondant au fragment. Assurez-vous que l'élément avec l'id existe dans le DOM au moment de la navigation.
Attention au timing
Si votre contenu est chargé de manière asynchrone, le scroll automatique pourrait ne pas fonctionner. Dans ce cas, vous devrez gérer le scroll manuellement après le chargement des données.
Récupérer le fragment actuel
Vous pouvez aussi réagir aux changements de fragments :
ts
import { ActivatedRoute } from '@angular/router';
export class UserComponent {
private route = inject(ActivatedRoute);
ngOnInit() {
this.route.fragment.subscribe(fragment => {
if (fragment) {
// Faire quelque chose avec le fragment
console.log('Fragment actuel:', fragment);
}
});
}
}
Scroll manuel avec ViewportScroller
Dans certains cas, vous pourriez avoir besoin de contrôler manuellement le scroll vers un fragment, notamment lorsque le contenu est chargé de manière asynchrone. Angular fournit le service ViewportScroller
pour gérer ce cas :
ts
import { Component, inject, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { ViewportScroller } from '@angular/common';
import { User } from './user.interface';
@Component({
standalone: true,
selector: 'app-user',
template: `
<div class="user-container">
<h1>Liste des utilisateurs</h1>
<div id="user-list">
@for (user of users; track user.id) {
<div class="user-card">
{{ user.name }}
</div>
}
</div>
</div>
`
})
export class UserComponent implements OnInit {
private route = inject(ActivatedRoute);
private viewportScroller = inject(ViewportScroller);
ngOnInit() {
this.route.fragment.subscribe(fragment => {
if (fragment) {
// Scroll manuel vers le fragment
this.viewportScroller.scrollToAnchor(fragment);
}
});
}
}
Le ViewportScroller
est particulièrement utile dans ces situations :
- Lorsque vous chargez des données de manière asynchrone
- Quand vous souhaitez ajouter un délai avant le scroll
- Pour implémenter un comportement de scroll personnalisé
Vous pouvez également utiliser d'autres méthodes du ViewportScroller
:
ts
// Scroll vers des coordonnées spécifiques
viewportScroller.scrollToPosition([0, 200]);
// Obtenir la position actuelle du scroll
const [x, y] = viewportScroller.getScrollPosition();
Tableau récapitulatif des méthodes ViewportScroller
Méthode | Description | Paramètres | Retour |
---|---|---|---|
setOffset() | Configure le décalage utilisé lors du défilement vers une ancre | [number, number] ou (() => [number, number]) | void |
getScrollPosition() | Récupère la position actuelle du scroll | - | [number, number] |
scrollToPosition() | Défile vers une position spécifique | [number, number] | void |
scrollToAnchor() | Défile vers un élément ancre | string (ID de l'élément) | void |
setHistoryScrollRestoration() | Configure la restauration automatique du scroll par le navigateur | "auto" ou "manual" | void |
CONSEIL
Utilisez setHistoryScrollRestoration()
avec le paramètre "manual"
si vous souhaitez gérer vous-même la position du scroll lors de la navigation dans l'historique.