本文へスキップ
BecomeCoder

Angularコース · 第6章 フォーム・ルーティング・通信 · レッスン16

フォーム ― Reactive Forms でユーザー入力を扱う

ローカル実施

導入

これまでのレッスンでは [value](input) を手作りで組み合わせて入力を扱ってきました(レッスン10など)。実務ではもっと多くの入力項目やバリデーション(入力チェック)を扱うため、Angularは専用の仕組み Reactive Forms を用意しています。

説明

ReactiveFormsModuleimports に加えると、FormControl(1つの入力欄を表す)や FormGroup(複数の FormControl をまとめたもの)が使えるようになります。

import { Component } from '@angular/core';
import { ReactiveFormsModule, FormGroup, FormControl, Validators } from '@angular/forms';

@Component({
  selector: 'app-root',
  standalone: true,
  imports: [ReactiveFormsModule],
  template: `
    <form [formGroup]="form" (ngSubmit)="submit()">
      <input formControlName="name" placeholder="お名前" />
      <input formControlName="email" placeholder="メールアドレス" />
      <button type="submit" [disabled]="form.invalid">送信</button>
    </form>
    <p *ngIf="form.get('email')?.invalid && form.get('email')?.touched">
      メールアドレスの形式が正しくありません
    </p>
  `,
})
export class AppComponent {
  form = new FormGroup({
    name: new FormControl('', Validators.required),
    email: new FormControl('', [Validators.required, Validators.email]),
  });

  submit(): void {
    console.log(this.form.value);
  }
}
flowchart TB
  fg["FormGroup(フォーム全体)"]
  fc1["FormControl: name<br/>Validators.required"]
  fc2["FormControl: email<br/>Validators.required + email"]
  fg --> fc1
  fg --> fc2
  fg -->|"form.valid / form.value"| submit["送信処理"]
  • FormControl … 入力欄1つぶんの値と状態(未入力か・バリデーション通過か・触れたか)を持つオブジェクトです。
  • FormGroup … 複数の FormControl をまとめたもの。まとめて form.validform.value を確認できます。
  • [formGroup]="form"formControlName="name" … テンプレートの <form>HTMLの入力欄を、クラス側の form に結び付けます。
  • Validators.required / Validators.email … あらかじめ用意されたバリデーションルール。自作の関数を渡すこともできます。
  • もっと簡易なテンプレート駆動フォーム[(ngModel)] を使う方法)もありますが、実務では入力項目が多い画面ほど Reactive Forms が好まれます(テストしやすく、ロジックがクラス側に集まるため)。

まとめ

フォームは「入力欄=FormControl」「まとまり=FormGroup」で表現され、テンプレート側は formGroupformControlName でクラス側と結び付きます。手元のプロジェクトで ReactiveFormsModule を試してみましょう。