0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

FormControlとSignalを使用した変更検知

Posted at

Angular v20 の**推奨スタイル(Signals/inject/toSignal/ライフサイクル不要)**で書き直すと、
以下のように class コンストラクタをやめて inject() を使い、OnInit を外し、valueChanges を toSignal に変換して effect で emit する構成がベスト。

✅ v20 推奨構成で書き換えたコード(最小・最もきれい)

ポイント:
• inject(FormBuilder) を使用(constructor 要らない)
• OnInit 廃止 → effect() で自動購読
• valueChanges を toSignal() で安全にシグナル化
• effect() 内で @Output() を emit
• FormGroup の型は NonNullable で安全に

child-form.component.ts(v20推奨版)

import { Component, Output, EventEmitter, effect, inject } from '@angular/core';
import { ReactiveFormsModule, FormBuilder, FormGroup } from '@angular/forms';
import { toSignal } from '@angular/core/rxjs-interop';

export type ChildFormValue = {
userName: string;
passWord: string;
};

@Component({
standalone: true,
selector: 'app-child-form',
imports: [ReactiveFormsModule],
template: <form [formGroup]="form"> <input formControlName="userName" placeholder="userName" /> <input formControlName="passWord" placeholder="passWord" /> </form>,
})
export class ChildFormComponent {
@Output() formChange = new EventEmitter();

private readonly fb = inject(FormBuilder);

// 型安全な FormGroup(NonNullable)
readonly form: FormGroup = this.fb.group({
userName: this.fb.nonNullable.control(''),
passWord: this.fb.nonNullable.control(''),
});

// valueChanges → signal 化(購読解除不要)
private readonly formValueSignal = toSignal(this.form.valueChanges, {
initialValue: this.form.getRawValue(),
});

constructor() {
// valueChanges の変化を自動検知して EventEmitter へ流す(OnInit不要)
effect(() => {
const v = this.formValueSignal();
this.formChange.emit(v);
});
}
}

✨ この書き方が「v20 推奨」な理由

✅ 1. constructor → inject() に置き換え

Angular v14〜で導入、v16〜推奨 → v20 はもはや標準。

✅ 2. ngOnInit を削除

valueChanges.subscribe() は手動 unsubscribe 必須。
toSignal() + effect() を使えば Angular が自動でライフサイクル管理する。

✅ 3. FormGroup の型安全性 UP

this.fb.nonNullable.control('')

により、string | null を避ける。

✅ 4. EventEmitter を発火する最小のパターン

effect() のみで OK
→ クリーンで subscription もない。

📌 完全に “今の Angular” の書き方

これが Angular v20〜v21 の公式推奨スタイルで、Signals との親和性が一番高い。

必要なら、これを使った「親側のシグナル同期コード」も書くよ

たとえば:

onFormChange(v: ChildFormValue) {
this.state.update(prev => ({ ...prev, form: v }));
}

みたいなやつ。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?