在用户离开angular 2应用程序的特定页面之前,我想提醒他们未保存的更改.通常我会使用window.onbeforeunload,但这不适用于单页应用程序.

我发现在angular 1中,你可以连接到$locationChangeStart事件,为用户抛出一个confirm框,但我没有看到任何东西显示如何让angular 2工作,或者该事件是否仍然存在.我还看到ag1的pluginsonbeforeunload提供了功能,但我也没有看到ag2使用它的任何方法.

我希望其他人找到了解决这个问题的办法;这两种方法都适用于我的目的.

推荐答案

为了涵盖针对浏览器刷新、关闭窗口等的防护(有关该问题的详细信息,请参阅@ChristopheVdal对Günter回答的 comments ),我发现在您的类的canDeactivate实现中添加@HostListener修饰符来监听beforeunload window事件会很有帮助.如果配置正确,这将同时防止应用内导航和外部导航.

例如:

Component:

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

Guard:

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.');
  }
}

Routes:

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

Module:

import { PendingChangesGuard } from './pending-changes.guard';
import { NgModule } from '@angular/core';

@NgModule({
  // ...
  providers: [PendingChangesGuard],
  // ...
})
export class AppModule {}

NOTE:正如@JasperRissee uw指出的,IE和Edge处理beforeunload事件的方式与其他浏览器不同,当beforeunload事件激活时(例如,浏览器刷新、关闭窗口等),IE和Edge将在确认对话框中包含单词false.在Angular 应用程序内导航不受影响,并将正确显示您指定的确认警告消息.那些需要支持IE/Edge并且不希望falsebeforeunload事件激活时在确认对话框中显示/希望显示更详细消息的用户,也可能希望查看@JasperRissee uw的解决方法答案.

Angular相关问答推荐

为什么当我在父组件中设置数组元素时,Angular重新创建子组件而不是更新它?

Angular路由不响应子路由的子路由

从Observatory的订阅方法外正确接收JSON数据

独立组件;依赖项注入

在RxJS和ANGING中处理多个API调用

Angular 17+独立配置中main.ts bootstrap 调用的最佳实践

升级到 Ng 16 - npm 错误!对等依赖冲突:@angular/compiler-cli@16.2.1

VS 2022 停留在运行 Angular 应用程序上

获取 Angular 中所有子集合 firestore 的列表

Angular 不使用NgRx的简单CRUD应用程序

TypeError:this.restoreDialogRef.afterClosed 不是函数

Angular 2如何使用路由和location.go()检测后退按钮按下?

Angular2 测试 - 按 ID 获取元素

请添加@Pipe/@Directive/@Component 注解

由于时区,Angular 4 日期管道显示错误的日期 - 如何解决这个问题?

如何在 ANGULAR 2 中提交表单时重置表单验证

检测指令中输入值何时更改

Firestore 从集合中获取文档 ID

如何在 Angular 2 中动态添加和删除表单字段

如何从materialAngular使用分页器?