Angular2-Routing の CanDeactivate ガードを使ってページ離脱前に警告を表示する
Angular と Angular2-Routing における「ページ離脱前に未保存の変更を警告する」機能の実装方法
Angular アプリケーションにおいて、ユーザーがページ遷移しようとした際に、未保存の変更がある場合に警告を表示する機能は、データの消失を防ぐために重要です。これは、Angular 自体の機能や Angular2-Routing モジュールを使って実装することができます。
Angular 自身の機能を使ってこの機能を実装するには、以下の手順が必要です。
CanDeactivate
インターフェースを実装するガードクラスを作成します。- ガードクラス内で、
canDeactivate
メソッドをオーバーライドし、以下の処理を行います。form.dirty
プロパティをチェックして、フォームに変更があるかどうかを確認します。- 変更がある場合は、確認ダイアログを表示し、ユーザーの意思を確認します。
- ユーザーがキャンセルを選択した場合は、遷移をキャンセルします。
CanDeactivate
ガードを@CanActivate
デコレータで修飾します。- ルーティング設定ファイルで、ガードクラスを必要なルートに関連付けます。
コード例
Angular の方法
import { Injectable } from '@angular/core';
import { CanDeactivate } from '@angular/router';
@Injectable()
export class MyGuard implements CanDeactivate {
canDeactivate() {
if (this.form.dirty) {
return confirm('変更内容が保存されていません。本当に移動しますか?');
}
return true;
}
}
Angular2-Routing モジュールの方法
import { CanActivate, CanDeactivate } from '@angular/router';
@Injectable()
export class MyGuard implements CanActivate, CanDeactivate {
canDeactivate() {
if (this.form.dirty) {
return confirm('変更内容が保存されていません。本当に移動しますか?');
}
return true;
}
}
const routes: Routes = [
{
path: 'my-route',
component: MyComponent,
canActivate: [MyGuard],
canDeactivate: [MyGuard]
}
];
補足
- 上記のコード例はあくまで基本的な例です。実際のアプリケーションでは、より複雑な処理が必要になる場合があります。
CanDeactivate
ガードは、複数のコンポーネントで共通して利用することができます。- Angular2-Routing モジュールには、
CanActivateChild
やCanLoad
などの他のガードも用意されています。
<form [formGroup]="form">
<input type="text" formControlName="name">
<button type="submit">送信</button>
</form>
import { Component, OnInit } from '@angular/core';
import { FormGroup, FormControl } from '@angular/forms';
import { CanDeactivate } from '@angular/router';
@Component({
selector: 'my-component',
templateUrl: './my-component.component.html'
})
export class MyComponent implements OnInit, CanDeactivate {
form: FormGroup;
constructor() {}
ngOnInit() {
this.form = new FormGroup({
name: new FormControl('')
});
}
canDeactivate() {
if (this.form.dirty) {
return confirm('変更内容が保存されていません。本当に移動しますか?');
}
return true;
}
}
<form [formGroup]="form">
<input type="text" formControlName="name">
<button type="submit">送信</button>
</form>
import { Component, OnInit } from '@angular/core';
import { FormGroup, FormControl } from '@angular/forms';
import { CanActivate, CanDeactivate } from '@angular/router';
@Injectable()
export class MyGuard implements CanActivate, CanDeactivate {
canDeactivate() {
if (this.form.dirty) {
return confirm('変更内容が保存されていません。本当に移動しますか?');
}
return true;
}
}
const routes: Routes = [
{
path: 'my-route',
component: MyComponent,
canActivate: [MyGuard],
canDeactivate: [MyGuard]
}
];
@NgModule({
imports: [
RouterModule.forRoot(routes)
],
declarations: [
MyComponent
],
bootstrap: [MyComponent]
})
export class AppModule { }
動作確認
上記コードを基にアプリケーションを作成し、実行します。
- フォームに値を入力します。
- 別のページへ遷移しようとします。
- 確認ダイアログが表示されます。
- 「OK」ボタンをクリックすると、ページ遷移します。
Angular と Angular2-Routing における「ページ離脱前に未保存の変更を警告する」機能の実装方法
import { Injectable } from '@angular/core';
import { CanDeactivate } from '@angular/router';
@Injectable()
export class MyGuard implements CanDeactivate {
canDeactivate() {
if (this.form.dirty) {
return confirm('変更内容が保存されていません。本当に移動しますか?');
}
return true;
}
}
import { CanActivate, CanDeactivate } from '@angular/router';
@Injectable()
export class MyGuard implements CanActivate, CanDeactivate {
canDeactivate() {
if (this.form.dirty) {
return confirm('変更内容が保存されていません。本当に移動しますか?');
}
return true;
}
}
const routes: Routes = [
{
path: 'my-route',
component: MyComponent,
canActivate: [MyGuard],
canDeactivate: [MyGuard]
}
];
上記の 2 つの方法以外にも、以下の方法で「ページ離脱前に未保存の変更を警告する」機能を実装することができます。
-
RxJS を使用する方法
-
ローカルストレージを使用する方法
どの方法を選択するかは、アプリケーションの要件や開発者の好みによって異なります。
angular angular2-routing