1. ホーム
  2. angular

[解決済み] ページを離れる前に、未保存の変更点を警告する

2022-04-27 03:54:20

質問

angular 2アプリの特定のページから離れる前に、保存されていない変更についてユーザーに警告したいのですが。通常、私は window.onbeforeunload しかし、これは単一ページのアプリケーションではうまくいきません。

angular 1では、このメソッドにフックできることがわかりました。 $locationChangeStart イベントを発生させ confirm ボックスが表示されますが、angular 2 でこれを動作させる方法を示しているものはありませんし、このイベントがまだ存在するかどうかもわかりません。また プラグイン の機能を提供するag1用の onbeforeunload しかし、ag2 に使用する方法はまだ見つかっていません。

この問題に対する解決策を誰かが見つけていることを期待しています。どちらの方法でも、私の目的には問題なく機能します。

解決方法は?

ブラウザのリフレッシュやウィンドウのクローズなどに対するガードもカバーするために。(この問題の詳細については、Günter の回答に対する @ChristopheVidal のコメントを参照してください)、私は、ブラウザのリフレッシュやウィンドウのクローズなどに対するガードもカバーするために、このファイルに @HostListener デコレータをクラスの canDeactivate をリッスンするための実装です。 beforeunload window イベントが発生します。正しく設定すれば、アプリ内と外部のナビゲーションを同時にガードすることができます。

例えば

コンポーネントです。

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

ガード

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

ルート

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

モジュールです。

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

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

ノート : JasperRisseeuw が指摘するように、IE と Edge は beforeunload イベントは他のブラウザとは異なっており、そのような場合には false が発生した場合、確認ダイアログで beforeunload イベントがアクティブになります (例: ブラウザの更新、ウィンドウを閉じるなど)。Angularアプリ内の移動は影響を受けず、指定した確認の警告メッセージが適切に表示されます。IE/Edgeをサポートする必要があり、かつ false を実行したときに、確認ダイアログでより詳細なメッセージを表示する/表示させることができます。 beforeunload イベントが発生した場合の回避策として、@JasperRisseeuw さんの回答も参照してください。