Lab 08 : Guard de désactivation
📖 Ressources
🚀 Code de départ
step-5-album-wholesale-v16-post-add-custom-async-validator
Continuez depuis le résultat du Lab 07. Si vous avez besoin d'une copie fraîche, utilisez step-5-album-wholesale-v16-post-add-custom-async-validator comme base et complétez d'abord les Labs 05–07.
Dans ce lab, vous allez empêcher les utilisateurs de perdre accidentellement des données de formulaire non sauvegardées en implémentant un guard CanDeactivate. Vous allez créer un guard fonctionnel qui demande confirmation aux utilisateurs, implémenter la logique de désactivation dans votre composant, et optionnellement remplacer les dialogues de confirmation du navigateur par Material Dialog.
📝 Instructions
Étape 1 : Créer le guard de désactivation
Créez un guard fonctionnel :
import { CanDeactivateFn } from '@angular/router';
export interface CanComponentDeactivate {
canDeactivate: () => boolean;
}
export const canDeactivateGuard: CanDeactivateFn<CanComponentDeactivate> = (component) => {
if (component.canDeactivate && !component.canDeactivate()) {
return confirm('Vous avez des modifications non sauvegardées. Quitter quand même ?');
}
return true;
};
Étape 2 : Implémenter dans le composant
Ajoutez la méthode canDeactivate au composant :
export class AlbumAddComponent implements CanComponentDeactivate {
private formSubmitted = false;
canDeactivate(): boolean {
return !this.albumForm.dirty || this.formSubmitted;
}
saveAlbum() {
this.formSubmitted = true;
// Logique de sauvegarde...
}
}
Étape 3 : Appliquer à la route
Ajoutez le guard à la route :
const routes: Routes = [
{
path: 'albums/add',
component: AlbumAddComponent,
canDeactivate: [canDeactivateGuard]
}
];
Étape bonus : Utiliser MatDialog au lieu de confirm()
Remplacez le confirm() du navigateur par Material Dialog :
import { inject } from '@angular/core';
import { MatDialog } from '@angular/material/dialog';
import { ConfirmDialogComponent } from './confirm-dialog.component';
export const canDeactivateGuard: CanDeactivateFn<CanComponentDeactivate> = (component) => {
if (component.canDeactivate && !component.canDeactivate()) {
const dialog = inject(MatDialog);
return dialog.open(ConfirmDialogComponent, {
data: { message: 'Vous avez des modifications non sauvegardées. Quitter quand même ?' }
}).afterClosed();
}
return true;
};
Composant de dialogue de confirmation simple :
@Component({
selector: 'app-confirm-dialog',
template: `
<h2 mat-dialog-title>Confirmer</h2>
<mat-dialog-content>{{ data.message }}</mat-dialog-content>
<mat-dialog-actions>
<button mat-button [mat-dialog-close]="false">Annuler</button>
<button mat-button [mat-dialog-close]="true" color="warn">Quitter</button>
</mat-dialog-actions>
`
})
export class ConfirmDialogComponent {
data = inject(MAT_DIALOG_DATA);
}