Signal Formありかも【Angular】

formのValidationロジックがtsファイル側にまとまるようになるのいいかもしれない。今までの記述方法だとReactiveFormでValidationを設定して、そのValidationがerrorなった場合テンプレート側で@ifでエラーメッセージを記述しないといけなかった。

ReactiveFormを使ったformの定義tsファイル

actorForm = new FormGroup({
  name: new FormControl(this.actor.name, [
    Validators.required,
    Validators.minLength(4),
  ]),
  role: new FormControl(this.actor.role),
  skill: new FormControl(this.actor.skill, Validators.required),
});

テンプレートファイル

<input
    type="text"
    id="name"
    name="name"
    class="form-control"
    required
    minlength="4"
    appForbiddenName="bob"
    [(ngModel)]="actor.name"
    #name="ngModel"
/>
@if (name.invalid && (name.dirty || name.touched)) {
<div class="alert">
    @if (name.hasError('required')) {
    <div>Name is required.</div>
    }
    @if (name.hasError('minlength')) {
    <div>Name must be at least 4 characters long.</div>
    }
</div>
}

Signal-Formを使ったformの定義tsファイル

...  loginModel = signal<LoginData>({
  email: '',
  password: '',
});
loginForm = form(this.loginModel, (schemaPath) => {
  required(schemaPath.email, {message: 'Email is required'});
  email(schemaPath.email, {message: 'Enter a valid email address'});
  required(schemaPath.password, {message: 'Password is required'});
});

signalFormでValidationを定義しておくとフォームの入力内容がエラーの場合、紐付いているフォームの下にValidationで定義したメッセージが表示される。テンプレート側でエラーメッセージを設定する必要がないので、ファイルの行き来が少なくなる。

SignalFormでのSubmit

SignalFormを使っていつもどおりのSubmitをしようとしたときに使用感が変わっていたので少し戸惑った。今までは(ngSubmit)を使ってフォーム送信イベントを制御していたけど、(submit)でイベントを受け取り@angular/form/signalssubmitを使って制御する形に変わっていた。

onSubmit(event: Event) {
event.preventDefault();
submit(this.loginForm, async () => {
const credentials = this.loginModel();
// In a real app, this would be async:
// await this.authService.login(credentials);
// console.log('Logging in with:', credentials);
// });  }

テンプレート側で$eventを受けとってデフォルトのイベント動作を止めた後、@angular/form/signalssubmitを使って制御する必要がある

参考文献