From 7ef3da50e153be0c2b45fded600420ce440c1c8b Mon Sep 17 00:00:00 2001 From: peggylicious Date: Tue, 24 Mar 2026 15:38:39 +0100 Subject: [PATCH] feat(65): refactor user form component from reactive form to signal form --- .../src/app/user-form.component.ts | 96 ++++++++----------- 1 file changed, 40 insertions(+), 56 deletions(-) diff --git a/apps/forms/65-signal-form-edition/src/app/user-form.component.ts b/apps/forms/65-signal-form-edition/src/app/user-form.component.ts index e9a6f91cb..de5b0d3f6 100644 --- a/apps/forms/65-signal-form-edition/src/app/user-form.component.ts +++ b/apps/forms/65-signal-form-edition/src/app/user-form.component.ts @@ -1,24 +1,19 @@ import { ChangeDetectionStrategy, Component, - effect, inject, input, + linkedSignal, } from '@angular/core'; import { rxResource } from '@angular/core/rxjs-interop'; -import { - FormControl, - FormGroup, - ReactiveFormsModule, - Validators, -} from '@angular/forms'; +import { form, FormField, min, required } from '@angular/forms/signals'; import { Router } from '@angular/router'; import { of } from 'rxjs'; import { FakeBackendService } from './fake-backend.service'; @Component({ selector: 'app-user-form', - imports: [ReactiveFormsModule], + imports: [FormField], template: `

@@ -30,7 +25,7 @@ import { FakeBackendService } from './fake-backend.service'; class="h-8 w-8 animate-spin rounded-full border-4 border-indigo-500 border-t-transparent">

} @else { -
+
@@ -87,20 +80,20 @@ import { FakeBackendService } from './fake-backend.service'; + [formField]="userForm.grade" + class="mt-1 block w-full rounded-md border border-gray-300 px-3 py-2 shadow-sm focus:border-indigo-500 focus:ring-indigo-500 focus:outline-none sm:text-sm" />
@@ -124,45 +117,36 @@ export class UserFormComponent { defaultValue: undefined, }); - userForm = new FormGroup({ - firstname: new FormControl('', { - nonNullable: true, - validators: [Validators.required], - }), - lastname: new FormControl('', { - nonNullable: true, - validators: [Validators.required], - }), - age: new FormControl(0, { - nonNullable: true, - validators: [Validators.required, Validators.min(0)], - }), - grade: new FormControl(0, { - nonNullable: true, - validators: [Validators.required], - }), + userModel = linkedSignal({ + source: this.userResource.value, + computation: (user) => { + return { + firstname: user?.firstname ?? '', + lastname: user?.lastname ?? '', + age: user?.age ?? 0, + grade: user?.grade ?? 0, + }; + }, }); - constructor() { - effect(() => { - const userValue = this.userResource.value(); - if (userValue) { - this.userForm.patchValue(userValue); - } else { - this.userForm.reset({ firstname: '', lastname: '', age: 0, grade: 0 }); - } - }); - } + userForm = form(this.userModel, (path) => { + required(path.firstname); + required(path.lastname); + required(path.age); + min(path.age, 0); + required(path.grade); + }); - onSubmit(): void { - if (this.userForm.valid) { + onSubmit(event: Event): void { + event.preventDefault(); + if (this.userForm().valid()) { const userValue = this.userResource.value(); const obs = userValue ? this.backend.updateUser({ - ...this.userForm.getRawValue(), + ...this.userForm().value(), id: userValue.id, }) - : this.backend.addUser(this.userForm.getRawValue()); + : this.backend.addUser(this.userForm().value()); obs.subscribe(() => { this.router.navigate(['/']);