Angularのリアクティブフォームでは、FormGroupやFormArrayを活用することで、より柔軟で複雑なフォーム構成を実現できます。
また、業務アプリにおいては入力内容の厳密な検証が求められるため、カスタムバリデーターの作成も重要な技術です。
本章ではこれらの応用的なフォーム操作について、具体例とともに解説します。

1. FormGroupとFormArrayによる複雑な構造
FormGroup
は複数のコントロールをグループ化するための構造です。
一方、FormArray
は、可変長の入力グループ(配列)を管理できます。
例えば、複数の住所や電話番号入力などに適しています。
■ FormGroupの例
this.profileForm = this.fb.group({
name: [''],
address: this.fb.group({
city: [''],
street: ['']
})
});
HTML:
<input formControlName="name" placeholder="名前"><br>
<div formGroupName="address"><br> <input formControlName="city" placeholder="市区町村"><br> <input formControlName="street" placeholder="番地"><br></div>
■ FormArrayの例
this.phoneForm = this.fb.group({
phones: this.fb.array([ this.fb.control('') ])
});
get phones() {
return this.phoneForm.get('phones') as FormArray;
}
this.phones.push(this.fb.control(''));
HTML(*ngFor使用):
<div formArrayName="phones"><br>
<div *ngFor="let phone of phones.controls; let i = index"><br>
<input [formControlName]="i" placeholder="電話番号 {{i + 1}}"><br>
</div><br>
</div>
2. 動的フォームの生成
データベースからの取得結果やユーザーの操作に応じて、フォーム項目を動的に追加・削除するケースでは、FormArrayを用いた実装が有効です。
■ 動的にフォームを構成する例
例:質問リストに応じてフォーム生成
this.questionForm = this.fb.group({ questions: this.fb.array([]) });
const questions = ['年齢', '職業', '経験年数'];
questions.forEach(q =>this.questions.push(this.fb.control('')));
get questions() {
return this.questionForm.get('questions') as FormArray;
}
このように、フォームの構造そのものをコードで柔軟に制御できます。
3. カスタムバリデーター
Angularのバリデーションには、標準のValidators
(required、minLengthなど)に加えて、独自の検証ルール(カスタムバリデーター)を定義可能です。
■ 同一パスワード確認のカスタムバリデーター
validators/password-match.validator.ts
:
import { AbstractControl, ValidationErrors, ValidatorFn } from '@angular/forms';
export function passwordMatchValidator(): ValidatorFn {
return (control: AbstractControl): ValidationErrors | null => {
const password = control.get('password');
const confirm = control.get('confirm');
if (password?.value !== confirm?.value) {
return { passwordMismatch: true };
}
return null;
};
}
使用例(フォーム定義時):
this.registerForm = this.fb.group({
password: [''],
confirm: ['']
}, { validators: passwordMatchValidator() });
テンプレートでのエラーメッセージ表示:
パスワードが一致していません
まとめ
Angularのリアクティブフォームは、FormGroupやFormArrayによって高度な入力構造を実現できます。動的なフォーム構築やカスタムバリデーションを通じて、ユーザーの使いやすさと開発の柔軟性を両立することが可能です。