Aller au contenu principal

Navigation

Fenêtre de confirmation avant de quitter la page

Cas 1 - Naviguer dans l'application Angular

  1. Enregistrement du guard canDeactivate sur la route qui doit afficher une fenêtre de confirmation et empêcher de quitter la page.
typologies.routes.ts
export const TYPOLOGIES_ROUTES: CustomRoutes = [
{
path: ':id',
title: 'TYPOLOGIES.DETAIL.TITLE',
component: TypologiesDetailPageComponent,
canDeactivate: [confirmBeforeDeactivateGuard] // application du garde sur la route
},
];

Le guard est commun (voir code) et s'utilise avec un composant qui implémente l'interface ComponentCanDeactive.

Remarque: Ce guard affiche spécifiquement la modal de confirmation, on pourrait définir un autre comportement en définissant un autre guard.

  1. Implémenter cette interface dans le composant de la page concernée

Cas simple :

export class TypologiesDetailHomeTabComponent implements ComponentCanDeactivate {
//...

canDeactivate(): boolean {
return monAttribut === true;
}
}

Cas se basant sur des sous-composants :

Lorsque des sous-composants participent au calcul de la méthode canDeactivate on utilise la directive confirmBeforeDeactivateHandler.
On la place sur chaque sous composant ce qui permet ensuite d'appeler la méthode canDeactivate en requêtant tous les éléments de la vue qui ont la directive sur eux.
La directive s'assure que le composant associé implémente bien l'interface canDeactivate.

Template du composant TypologiesDetailHomeTabComponent
<!-- sous composant 1 -->
<!-- on place une référence #domainesList sur le composant et on la passe à confirmBeforeDeactivateHandler -->
<typologies-detail-tab-home-domaines-list
[confirmBeforeDeactivateHandler]="domainesList"
[domaines]="vm.typologie.domainesConvention"
[statusSummary]="vm.statusSummary"
#domainesList
></typologies-detail-tab-home-domaines-list>
<!-- sous composant 2 -->
<typologies-detail-tab-home-options
[confirmBeforeDeactivateHandler]="options"
[statusSummary]="vm.statusSummary"
[typologie]="vm.typologie"
#options
></typologies-detail-tab-home-options>

On récupère les composants implémentant CanDeactivate par requête avec @ViewChildren.
Ensuite on boucle sur ces éléments pour le calcul.

export class TypologiesDetailHomeTabComponent implements ComponentCanDeactivate {
//...

@ViewChildren(ConfirmBeforeDeactivateHandlerDirective)
confirmBeforeDeactivateHandlers!: QueryList<
ConfirmBeforeDeactivateHandlerDirective<ComponentCanDeactivate>
>;

canDeactivate(): boolean {
return (monAttribut === true) ||
!this.confirmBeforeDeactivateHandlers.some(
(dir) => !dir.confirmBeforeDeactivateHandler.canDeactivate(),
);
}
}

Cas 2 - Action sur le navigateur (quitter l'onglet, rafraichir la page,..)

Il est impossible de customiser la fenêtre dans ce cas là - docs

export class TypologiesDetailHomeTabComponent implements ComponentCanDeactivate {
//...

@HostListener('window:beforeunload') // on se plug sur la méthode qui calcul si le composant peut être désactivé
canDeactivate(): boolean {
return aTruthyValueWillDisplayTheConfirmationDialog;
}
}

Lorsque l'on veut naviguer sur un bloc d'une page, on utilise un fragment d'url pour cibler l'id du bloc.
Exemple : Navigation vers un bloc depuis une alerte nécessitant une action.

  1. Utilisation d'une pipe (voir code) pour homogénéiser l'id du bloc cible.
    Cela permet également de facilement rechercher les blocs qui sont ciblés par des navigations.
typologies/components/detail/visa-tab/circuit-list/circuit-list.component.html
<ng-container detailBlocTitle>
<!-- id used for direct navigation to this bloc -->
<h2 id="{{ 'circuit-visa' | htmlIdAnchorBloc }}">
{{ 'TYPOLOGIES.DETAIL.TAB_VISA.BLOC_CIRCUIT_LIST.TITLE' | translate }}
</h2>
</ng-container>
  1. Utilisation d'un lien pointant sur ce fragment
typologies/components/detail/alerts/alerts.component.html
<a
routerLink="./visa"
fragment="{{ 'circuit-visa' | htmlIdAnchorBloc }}"
class="btn btn-primary"
>
{{
'TYPOLOGIES.DETAIL.ALERTS.SHOULD_VISEURS_HAVE_PRIVILLEGE.BTN_SHOW_CIRCUIT'
| translate
}}
</a>