Signal Forms 자동 상태 클래스가 추가되었습니다 (그리고 더 많은 기능)
Source: Dev.to
이 Signal Form이 어떻게 구성되는지 살펴보자
Styles
컴포넌트의 SCSS는 여전히 기존 ng- 클래스를 대상으로 합니다:
input {
/* touched vs untouched */
&.ng-untouched {
background-color: rgba(white, 0.05);
}
&.ng-touched {
background-color: rgba(#007bff, 0.15);
}
/* dirty vs pristine */
&.ng-dirty {
box-shadow: 0 0 0 2px rgba(#007bff, 0.12);
}
/* valid vs invalid */
&.ng-touched.ng-invalid {
border-color: #e53935;
}
&.ng-touched.ng-valid {
border-color: #43a047;
}
/* pending */
&.ng-pending {
border-color: orange;
}
}
Template Walkthrough: The New [field] Directive
[field] 디렉티브는 입력을 Signal Form의 Field 객체에 직접 바인딩하여 value, touched, dirty, valid, pending 신호를 노출합니다.
디버그 패널에서 실시간 상태를 확인할 수 있습니다:
@let username = form.username();
Field State
touched: {{ username.touched() }}
dirty: {{ username.dirty() }}
valid: {{ username.valid() }}
pending: {{ username.pending() }}
기존 클래스를 수동으로 추가할 수도 있지만 번거롭습니다.
TypeScript Deep Dive: Model and form()
import { signal, form } from '@angular/forms/signals';
import { required, minLength } from '@angular/forms';
interface SignUpForm {
username: string;
}
// Writable signal that holds the form’s data
protected model = signal({
username: '',
});
// Connect the model to the Signal Form API
protected form = form(this.model, s => {
s.username(required(), minLength(3));
});
model은 폼 데이터의 진실된 소스를 나타내는 writable signal입니다.form(this.model, …)은 Signal Form 인스턴스를 생성하여 모델을 검증 로직에 연결합니다.s.username빌더를 통해required()와minLength()같은 검증기를 붙일 수 있습니다.
Restoring Automatic ng-* Classes (and Customizing Them)
Angular 21은 Signal Forms용 provideStateClasses 설정을 도입했습니다. 컴포넌트의 providers 배열(또는 전역) 에 추가하면 프레임워크가 각 필드의 신호에 따라 기존 ng- 클래스를 자동으로 적용합니다.
import { Component } from '@angular/core';
import { provideStateClasses } from '@angular/forms';
@Component({
selector: 'app-signup',
templateUrl: './form.component.html',
styleUrls: ['./form.component.scss'],
providers: [provideStateClasses()] // <-- enables automatic ng-* classes
})
export class FormComponent {
// model and form definitions as shown above
}
Custom Class Prefixes
다른 네이밍 방식을 원한다면 provideStateClasses에 옵션 객체를 전달할 수 있습니다:
providers: [
provideStateClasses({
prefix: 'sf-', // e.g., sf-touched, sf-dirty, …
map: {
touched: 'my-touched',
dirty: 'my-dirty',
valid: 'my-valid',
invalid: 'my-invalid',
pending: 'my-pending'
}
})
]
prefix는 생성되는 모든 클래스에 사용자 정의 접두사를 추가합니다.map은 개별 상태 클래스의 이름을 바꿀 수 있게 해줍니다.
이 설정을 사용하면 기존 SCSS를 새로운 클래스 이름에 맞게 수정하거나, 기본 ng- 접두사를 그대로 사용해 원래 선택자를 유지할 수 있습니다.
Summary
- Reactive Forms에서는
ng-*상태 클래스가 자동으로 적용됐지만, Signal Forms는 처음에 이를 생략했습니다. - Angular 21.0.1은
provideStateClasses를 통해 자동 클래스 생성을 다시 도입했습니다. - 이 프로바이더는 기본
ng-접두사와 함께 바로 동작하거나, 접두사와 명시적 매핑을 통해 커스터마이징할 수 있습니다. - 각 컨트롤에 클래스를 수동으로 바인딩할 필요가 없으며, Angular가 이를 처리해 기존 스타일이 Signal Forms로 마이그레이션한 뒤에도 그대로 작동합니다.