Untuk juga melindungi penjaga dari penyegaran browser, menutup jendela, dll. (Lihat komentar @ ChristopheVidal untuk jawaban Günter untuk detail tentang masalah ini), saya merasa terbantu untuk menambahkan @HostListener
dekorator ke canDeactivate
implementasi kelas Anda untuk mendengarkan beforeunload
window
acara tersebut. Jika dikonfigurasi dengan benar, ini akan melindungi dari navigasi dalam aplikasi dan eksternal pada saat yang bersamaan.
Sebagai contoh:
Komponen:
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
}
}
Menjaga:
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.');
}
}
Rute:
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 {}
CATATAN : Seperti yang ditunjukkan oleh @JasperRisseeuw, IE dan Edge menangani beforeunload
acara secara berbeda dari browser lain dan akan menyertakan kata false
dalam dialog konfirmasi saat beforeunload
acara diaktifkan (misalnya, browser menyegarkan, menutup jendela, dll.). Menavigasi dalam aplikasi Angular tidak terpengaruh dan akan menampilkan pesan peringatan konfirmasi yang Anda tunjuk dengan benar. Mereka yang perlu mendukung IE / Edge dan tidak ingin false
menampilkan / menginginkan pesan yang lebih mendetail di dialog konfirmasi saat beforeunload
acara diaktifkan mungkin juga ingin melihat jawaban @ JasperRisseeuw untuk mengatasinya.