Để bảo vệ chống lại việc làm mới trình duyệt, đóng cửa sổ, v.v. (xem nhận xét của @ ChristopheVidal về câu trả lời của Günter để biết chi tiết về vấn đề này), tôi thấy hữu ích khi thêm trình @HostListener
trang trí vào phần canDeactivate
triển khai của lớp bạn để lắng nghe beforeunload
window
sự kiện. Khi được định cấu hình chính xác, điều này sẽ bảo vệ chống lại cả điều hướng trong ứng dụng và điều hướng bên ngoài cùng một lúc.
Ví dụ:
Thành phần:
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
}
}
Bảo vệ:
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.');
}
}
Các tuyến:
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] },
];
Mô-đun:
import { PendingChangesGuard } from './pending-changes.guard';
import { NgModule } from '@angular/core';
@NgModule({
// ...
providers: [PendingChangesGuard],
// ...
})
export class AppModule {}
LƯU Ý : Như @JasperRisseeuw đã chỉ ra, IE và Edge xử lý beforeunload
sự kiện khác với các trình duyệt khác và sẽ bao gồm từ này false
trong hộp thoại xác nhận khi beforeunload
sự kiện kích hoạt (ví dụ: làm mới trình duyệt, đóng cửa sổ, v.v.). Điều hướng đi trong ứng dụng Angular không bị ảnh hưởng và sẽ hiển thị đúng thông báo cảnh báo xác nhận được chỉ định của bạn. Những người cần hỗ trợ IE / Edge và không muốn false
hiển thị / muốn thông báo chi tiết hơn trong hộp thoại xác nhận khi beforeunload
sự kiện kích hoạt cũng có thể muốn xem câu trả lời của @ JasperRisseeuw để biết cách giải quyết.