Ich habe es als hilfreich empfunden, den @HostListener
Dekorator zur canDeactivate
Implementierung Ihrer Klasse hinzuzufügen , um auf das beforeunload
window
Ereignis zu warten, um auch Schutz vor Browseraktualisierungen, Schließen des Fensters usw. abzudecken (siehe @ ChristopheVidals Kommentar zu Günters Antwort für Details zu diesem Problem) . Bei korrekter Konfiguration schützt dies gleichzeitig vor In-App- und externer Navigation.
Beispielsweise:
Komponente:
import { ComponentCanDeactivate } from './pending-changes.guard';
import { HostListener } from '@angular/core';
import { Observable } from 'rxjs/Observable';
export class MyComponent implements ComponentCanDeactivate {
// @HostListener allows us to also guard against browser refresh, close, etc.
@HostListener('window:beforeunload')
canDeactivate(): Observable<boolean> | boolean {
// insert logic to check if there are pending changes here;
// returning true will navigate without confirmation
// returning false will show a confirm dialog before navigating away
}
}
Bewachen:
import { CanDeactivate } from '@angular/router';
import { Injectable } from '@angular/core';
import { Observable } from 'rxjs/Observable';
export interface ComponentCanDeactivate {
canDeactivate: () => boolean | Observable<boolean>;
}
@Injectable()
export class PendingChangesGuard implements CanDeactivate<ComponentCanDeactivate> {
canDeactivate(component: ComponentCanDeactivate): boolean | Observable<boolean> {
// if there are no pending changes, just allow deactivation; else confirm first
return component.canDeactivate() ?
true :
// NOTE: this warning message will only be shown when navigating elsewhere within your angular app;
// when navigating away from your angular app, the browser will show a generic warning message
// see http://stackoverflow.com/a/42207299/7307355
confirm('WARNING: You have unsaved changes. Press Cancel to go back and save these changes, or OK to lose these changes.');
}
}
Routen:
import { PendingChangesGuard } from './pending-changes.guard';
import { MyComponent } from './my.component';
import { Routes } from '@angular/router';
export const MY_ROUTES: Routes = [
{ path: '', component: MyComponent, canDeactivate: [PendingChangesGuard] },
];
Modul:
import { PendingChangesGuard } from './pending-changes.guard';
import { NgModule } from '@angular/core';
@NgModule({
// ...
providers: [PendingChangesGuard],
// ...
})
export class AppModule {}
HINWEIS : Wie @JasperRisseeuw hervorhob, behandeln IE und Edge das beforeunload
Ereignis anders als andere Browser und fügen das Wort false
in den Bestätigungsdialog ein, wenn das beforeunload
Ereignis aktiviert wird (z. B. Aktualisieren des Browsers, Schließen des Fensters usw.). Das Navigieren innerhalb der Angular-App bleibt davon unberührt und zeigt die angegebene Bestätigungswarnmeldung ordnungsgemäß an. Diejenigen, die IE / Edge unterstützen müssen und bei Aktivierung false
des beforeunload
Ereignisses keine detailliertere Meldung im Bestätigungsdialog anzeigen / möchten, möchten möglicherweise auch die Antwort von @ JasperRisseeuw für eine Problemumgehung sehen.