Aller au contenu principal

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);
}