mcpField
A
angular-forms

angular-forms

github.com/gentleman-programming開発663150 回インストール32 週間前に更新
リポジトリ

angular-forms について

Angularでフォームを実装する開発者向けのスキルです。Signal Forms、Reactive Forms、テンプレート駆動フォームの使い分けに加え、型安全性やネスト構造を説明します。

主な機能

  1. 013種類のフォーム方式の比較
  2. 02Signal Formsの型付きフィールドアクセス
  3. 03型安全な同期Reactive Formsの構築
  4. 04ネストしたフォームとFormArrayの作成

活用シーン

  1. 01新しいアプリでSignal Formsを選択
  2. 02本番アプリでReactive Formsを実装
  3. 03単純なフォームにテンプレート駆動方式を採用

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/gentleman-programming/gentleman-skills --skill angular-forms

インストール後、Claude Code で/angular-formsを入力して読み込まれたか確認します。

詳細

用途に応じた選び方

用途推奨
シグナルを使用する新規アプリシグナルフォーム(実験的)
本番環境のアプリリアクティブフォーム
シンプルなフォームテンプレート駆動フォーム

シグナルフォーム(v21+、実験的)

import { form, FormField, required, email } from '@angular/forms/signals';

@Component({
  imports: [FormField],
  template: `
    <form>
      <input [formField]="emailField" type="email" />
      <input [formField]="passwordField" type="password" />
      <button (click)="submit()">Login</button>
    </form>
  `
})
export class LoginComponent {
  readonly loginForm = form({
    email: ['', [required, email]],
    password: ['', required]
  });
  
  readonly emailField = this.loginForm.controls.email;
  readonly passwordField = this.loginForm.controls.password;
  
  submit() {
    if (this.loginForm.valid()) {
      const values = this.loginForm.value();
    }
  }
}
シグナルフォームのメリット
  • 自動双方向バインディング
  • 型安全なフィールドアクセス
  • スキーマベースのバリデーション
  • シグナルを基盤として構築

リアクティブフォーム(本番環境向け)

import { FormBuilder, Validators, ReactiveFormsModule } from '@angular/forms';

@Component({
  imports: [ReactiveFormsModule],
  template: `
    <form [formGroup]="form" (ngSubmit)="submit()">
      <input formControlName="email" type="email" />
      <input formControlName="password" type="password" />
      <button type="submit" [disabled]="form.invalid">Login</button>
    </form>
  `
})
export class LoginComponent {
  private readonly fb = inject(FormBuilder);

  form = this.fb.nonNullable.group({
    email: ['', [Validators.required, Validators.email]],
    password: ['', [Validators.required, Validators.minLength(8)]],
  });
  
  submit() {
    if (this.form.valid) {
      const { email, password } = this.form.getRawValue();
    }
  }
}
要点
  • 型安全性のため、必ず fb.nonNullable.group() を使用します
  • 型付きの値を取得するには getRawValue() を使用します
  • リアクティブフォームは同期的です(テストが容易です)

ネストされたフォームと FormArray

form = this.fb.nonNullable.group({
  name: [''],
  address: this.fb.group({
    street: [''],
    city: [''],
  }),
  phones: this.fb.array([this.fb.control('')]),
});

get phones() {
  return this.form.get('phones') as FormArray;
}

addPhone() {
  this.phones.push(this.fb.control(''));
}

リソース

コメント