Angularフォームの高度化

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


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> &nbsp;&nbsp;<input formControlName="city" placeholder="市区町村"><br> &nbsp;&nbsp;<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> &nbsp;&nbsp;
 <div *ngFor="let phone of phones.controls; let i = index"><br>&nbsp;&nbsp;&nbsp;&nbsp;
  <input [formControlName]="i" placeholder="電話番号 {{i + 1}}"><br>&nbsp;&nbsp;
 </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によって高度な入力構造を実現できます。動的なフォーム構築やカスタムバリデーションを通じて、ユーザーの使いやすさと開発の柔軟性を両立することが可能です。

採用情報 長谷川 横バージョン
SHARE
PHP Code Snippets Powered By : XYZScripts.com