Aller au contenu

Lab 08 : Guard de désactivation

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.

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

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...
}
}

Ajoutez le guard à la route :

const routes: Routes = [
{
path: 'albums/add',
component: AlbumAddComponent,
canDeactivate: [canDeactivateGuard]
}
];

Étape bonus : Utiliser MatDialog au lieu de confirm()

Section intitulée « É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);
}