Angular Reactive Forms:フォームを初期状態に戻しつつ、入力データを保持する方法
Angular でフォームをプリスティン状態に設定する方法(データ消去なし)
しかし、単に form.reset()
を呼び出すと、フォームに入力されたデータもすべて消去されてしまいます。場合によっては、データは保持したいが、フォームの状態だけをプリスティンにしたいというケースがあります。
そこで今回は、Angular Reactive Forms を使用して、フォームをプリスティン状態に設定しつつ、入力されたデータを保持する方法について解説します。
フォームコントロールの markAsPristine() メソッドを使用する
各フォームコントロールには、markAsPristine()
メソッドが用意されています。このメソッドを呼び出すことで、そのコントロールをプリスティン状態に設定することができます。
this.myFormControl.markAsPristine();
この方法の利点は、個々のフォームコントロールを個別にプリスティン状態に設定できることです。一方、複数のフォームコントロールを一括でプリスティン状態に設定したい場合は、以下の方法が適しています。
フォームグループの resetForm() メソッドを使用する
フォームグループには、resetForm()
メソッドが用意されています。このメソッドを呼び出すことで、そのグループ内のすべてのフォームコントロールをプリスティン状態に設定することができます。
this.myFormGroup.resetForm();
フォームグループの patchValue() メソッドを使用する
フォームグループの patchValue()
メソッドを使用して、フォームコントロールの値を個別に更新することもできます。この場合、pristine
属性を true
に設定することで、そのコントロールをプリスティン状態に設定することができます。
this.myFormGroup.patchValue({
myFormControl: {
value: this.myFormControl.value,
pristine: true
}
});
この方法の利点は、フォームコントロールの値を更新しつつ、そのコントロールをプリスティン状態に設定できることです。
上記のように、Angular Reactive Forms には、フォームをプリスティン状態に設定しつつ、入力されたデータを保持する方法がいくつか用意されています。それぞれの方法の利点を理解し、状況に応じて適切な方法を選択してください。
- 上記のコード例は、Angular 8 以降を使用していることを前提としています。
import { Component, OnInit } from '@angular/core';
import { FormControl } from '@angular/forms';
@Component({
selector: 'app-form-control-pristine',
template: `
<input type="text" [(ngModel)]="myFormControl.value">
<button (click)="markAsPristine()">プリスティン状態に設定</button>
`
})
export class FormControlPristineComponent implements OnInit {
myFormControl = new FormControl('', Validators.required);
constructor() { }
ngOnInit() { }
markAsPristine() {
this.myFormControl.markAsPristine();
}
}
このコードでは、myFormControl
というフォームコントロールを作成し、markAsPristine()
メソッドを使用してプリスティン状態に設定しています。
import { Component, OnInit } from '@angular/core';
import { FormGroup, FormControl } from '@angular/forms';
@Component({
selector: 'app-form-group-pristine',
template: `
<form [formGroup]="myFormGroup">
<input type="text" formControlName="firstName">
<input type="text" formControlName="lastName">
<button type="button" (click)="resetForm()">プリスティン状態に設定</button>
</form>
`
})
export class FormGroupPristineComponent implements OnInit {
myFormGroup = new FormGroup({
firstName: new FormControl('', Validators.required),
lastName: new FormControl('', Validators.required)
});
constructor() { }
ngOnInit() { }
resetForm() {
this.myFormGroup.resetForm();
}
}
import { Component, OnInit } from '@angular/core';
import { FormGroup, FormControl } from '@angular/forms';
@Component({
selector: 'app-form-group-patch-value',
template: `
<form [formGroup]="myFormGroup">
<input type="text" formControlName="firstName">
<input type="text" formControlName="lastName">
<button type="button" (click)="patchValue()">プリスティン状態に設定</button>
</form>
`
})
export class FormGroupPatchValueComponent implements OnInit {
myFormGroup = new FormGroup({
firstName: new FormControl('', Validators.required),
lastName: new FormControl('', Validators.required)
});
constructor() { }
ngOnInit() { }
patchValue() {
this.myFormGroup.patchValue({
firstName: this.myFormGroup.get('firstName').value,
lastName: this.myFormGroup.get('lastName').value,
pristine: true
});
}
}
this.myFormControl.setValue({});
reset()
メソッドを使用して、フォームグループを初期状態にリセットすることもできます。この場合、pristine
属性も true
に設定されますが、フォームコントロールの値はすべて消去されてしまいます。
this.myFormGroup.reset();
カスタムバリデーションロジックを使用する
カスタムバリデーションロジックを使用して、フォームコントロールの状態を制御することもできます。例えば、以下のようなカスタムバリデーションロジックを作成することができます。
import { AbstractControl, ValidationErrors } from '@angular/forms';
export function pristineValidator(control: AbstractControl): ValidationErrors | null {
if (control.pristine) {
return { pristine: true };
} else {
return null;
}
}
このカスタムバリデーションロジックを使用すると、フォームコントロールがプリスティン状態である場合にのみエラーメッセージを表示することができます。
RxJS を使用する
RxJS を使用して、フォームコントロールの状態を監視し、プリスティン状態になったときに処理を実行することもできます。例えば、以下のようなコードで myFormControl
がプリスティン状態になったときにコンソールにログを出力することができます。
import { fromEvent } from 'rxjs';
fromEvent(this.myFormControl, 'statusChange')
.pipe(
filter(event => event.status === 'PRISTINE')
)
.subscribe(() => {
console.log('Form control is pristine');
});
angular angular-reactive-forms