- 시그널 폼은 기존의 폼그룹/폼컨트롤 관련 코드의 상당 부분을 강력한 형식의 시그널 기반 필드트리로 대체하여 데이터 모델을 그대로 반영합니다.
- 유효성 검사는 중앙 집중식으로 반응하며, 재사용 가능한 스키마, 조건부 규칙, 비동기 HTTP 검사, 메타데이터 및 필드 간 로직을 수동 구독 없이 지원합니다.
- 범용 [field] 지시문과 경량 FormValueControl 계약을 통해 사용자 지정 컨트롤 및 하위 폼을 쉽게 만들 수 있으며, compatForm()을 사용하면 반응형 폼에서 점진적으로 마이그레이션할 수 있습니다.
- 디바운싱, 제출 상태 처리, Zod 또는 표준 스키마 라이브러리와의 통합과 같은 고급 기능 덕분에 Signal Forms는 복잡한 프로덕션 수준의 사용 사례에 적합합니다.

Angular 21은 Signal Forms라는 완전히 새로운 폼 구축 방식을 제공합니다. Signal Forms는 기존의 FormControl/FormGroup 관련 코드를 대폭 대체하는 시그널 우선 API로, 폼 상태를 반응형 아키텍처의 자연스러운 일부처럼 느껴지게 합니다. 값 변경 스트림, 수동 구독 및 복잡한 타입 조작과 씨름하는 대신, 강력한 타입의 필드 트리, 선언적 유효성 검사 및 Angular 시그널 기반의 자동 UI 동기화를 활용할 수 있습니다.
만약 여러분이 null 허용 컨트롤 타입, get() 메서드에서 사용하는 불안정한 문자열 기반 경로, 또는 ControlValueAccessor를 사용하는 복잡한 절차에 짜증을 느낀 적이 있다면, Signal Forms는 Angular 개발자들이 오랫동안 기다려온 신선한 바람처럼 느껴질 것입니다. 아직 실험적인 기능으로 표시되어 있지만, 간단한 로그인 폼부터 비동기 유효성 검사, 조건부 로직, 하위 폼, 디바운싱, 기존 반응형 폼에서 원활하게 마이그레이션할 수 있는 경로까지, 깊이 중첩된 스키마 기반 폼에 이르기까지 모든 것을 이미 지원합니다.
Angular 시그널 폼이란 무엇이며 언제 사용해야 할까요?
Signal Forms는 Angular 21 이상에 내장된 실험적인 라이브러리로, Observable이나 명령형 API 대신 시그널을 기반으로 폼 상태를 관리합니다. 개념적으로, 당신은 다음을 정의합니다. 폼 모델 데이터 구조를 담고 있는 쓰기 가능한 신호로 사용한 다음, form() ~에서 기능 @angular/forms/signals 모델 형태를 그대로 반영하는 강력한 형식의 FieldTree를 생성합니다.
이 FieldTree는 각 필드를 반응형 상태 객체(값, 유효성, 변경/수정 플래그, 대기 상태 등)를 반환하는 함수로 노출하며, 이러한 필드를 단일 메서드를 통해 템플릿에 연결합니다. 지침. 그 결과, UI 컨트롤과 기본 모델 신호 간에 자동 양방향 동기화가 이루어지며, 오류 발생 가능성이 높은 문자열 경로 대신 점 표기법과 배열 인덱스를 사용하여 타입 안전한 탐색이 가능해집니다.
시그널 폼은 이미 코어에 포함되어 있습니다. @angular/forms 패키지는 제공되지만, 실험적인 진입점을 가져오려면 해당 기능을 임포트해야 합니다. @angular/forms/signals 새로운 API에 접근하기 위해서입니다. 템플릿의 경우, 가져오기 및 선언을 수행합니다. Field 컴포넌트의 import 문에 디렉티브를 추가하여 모든 컨트롤을 바인딩할 수 있도록 하세요. 보다는 formControl, formControlName, formGroupName및 formArrayName.

핵심 아키텍처: 폼 모델, 필드트리 및 지령
시그널 폼을 사용할 때 가장 중요한 사고방식의 변화는 폼 모델 시그널이 데이터의 유일한 진실의 원천이 되고, 생성된 폼은 단순히 해당 모델을 동기화하여 반영하고 변형한다는 점입니다. 일반적으로 이메일과 비밀번호가 포함된 로그인 페이로드와 같은 초기 폼 데이터를 사용하여 쓰기 가능한 시그널을 선언하는 것으로 시작합니다.
이 모델을 전달합니다 form(model, schema?) 객체의 구조를 거의 일대일로 반영하는 FieldTree를 생성하므로 모델의 모든 속성 또는 중첩 객체가 폼 트리의 형식화된 필드 노드가 됩니다. 기본 데이터 유형(문자열, 숫자, 부울, 날짜 문자열 등)은 리프 노드가 되고, 객체와 배열은 컨테이너 역할을 하여 도메인 모델과 일치하는 계층적 탐색을 제공합니다.
각 필드 노드는 점 표기법으로 접근하며, 배열의 경우 표준 인덱스 접근 방식을 사용합니다. myForm.users.email이는 TypeScript의 타입 추론과 긴밀하게 통합되어 있습니다. 해당 필드를 함수로 호출할 때 (예를 들어) myForm.email()그러면 반응형 필드 상태 객체가 노출됩니다. value(), valid(), invalid(), dirty(), touched(), pending(), errors(), reset() 그리고 추가적인 도우미들.
FieldTree를 DOM에 연결하는 작업은 단일 메서드로 처리됩니다. 네이티브 입력에 사용할 수 있는 지시어입니다. mat-select의 관리텍스트 영역, 라디오 버튼, 체크박스 또는 간단한 FormValueControl 또는 FormCheckboxControl 계약을 구현하는 모든 사용자 지정 구성 요소 또는 지시문. 이 지시문은 양방향 값 동기화, 포커스/터치 상태, 필수 플래그, 비활성화/읽기 전용 상태, 유효성 검사 메타데이터 등을 관리하며, 사용자가 직접 코드를 작성할 필요가 없습니다.
내부적으로는 FieldTree가 이는 모델 유형을 재귀적으로 탐색하여 정확히 일치하는 폼 API를 생성하는 정교한 매핑 유형으로, 모든 경로에 대해 컴파일 시간 안전성을 제공하고 템플릿에서 오타나 유형 불일치를 바로 잡아냅니다. 이는 문자열 기반 방식보다 훨씬 발전된 것입니다. get('user.email') TypeScript가 컴파일 시점에 경로의 유효성을 검사할 방법이 없었던 Reactive Forms 호출.
기존 반응형 폼에 비해 타이핑 방식의 장점이 있습니다.
Angular 14에서 도입된 타입이 지정된 반응형 폼은 큰 진전이었지만, TypeScript의 장점을 완전히 활용하지 못한 오래된 API 위에 구축되어 있어 다음과 같은 지속적인 불편함을 초래했습니다. T | null 가치는 도처에 존재한다. 반면, 시그널 폼은 모델 시그널에서 직접 파생된 엄격한 유형 지정을 기반으로 처음부터 설계되었습니다.
반응형 폼을 사용하면 모든 FormControl이 사실상 반응형 폼이 됩니다. FormControl<T | null> 명시적으로 선택하지 않는 한 nonNullable 각 컨트롤에 대해, 이는 폼 정의 전체에 걸쳐 노이즈와 반복적인 구성을 확산시킵니다. 시그널 폼은 초기 모델에서 정확한 유형을 추론함으로써 이 문제를 해결합니다. 따라서 모델의 유형이 email null을 허용하지 않는 문자열입니다. myForm.email().value() 단지 string가 아닌 string | null.
또 다른 주요 문제점은 사용 시 타입 정보가 손실되는 문제입니다. get() 반응형 폼에서 문자열 경로를 사용하면 필연적으로 오류가 발생합니다. AbstractControl<unknown, unknown> | null 그리고 모든 곳에 보기 흉한 타입 어설션을 강제로 삽입합니다. 시그널 폼에서는 절대 호출하지 않습니다. get('user.email'); 간단히 탐색하시면 됩니다 myForm.user.email또한 오타나 잘못된 속성 이름은 런타임 버그가 아닌 컴파일 오류를 발생시킵니다.
배열은 이러한 구조 보존 설계의 이점을 더욱 많이 누립니다. FormArray는 종종 제네릭으로 축소되지만 말입니다. AbstractControl 사용 시 유형을 지정할 때 at() 또는 중첩 get()시그널 폼은 인덱싱할 때 각 요소와 해당 속성에 대한 전체 타입 정보를 유지합니다. myForm.users.name 또는 반복합니다 for (const of myForm.users). TypeScript는 요소 유형을 이해하므로 전체 중첩 트리에 걸쳐 IntelliSense 및 엄격한 검사를 수행할 수 있습니다.
모델이 진실의 원천이 되기 때문에 동적 폼을 이해하기가 더 쉬워집니다. 런타임에 임의의 FormControl을 FormGroup에 추가하여 구조적 타입을 잃는 대신, 모델 신호를 업데이트(예: 선택적 속성 추가 또는 배열에 요소 추가)하면 FormTree가 그에 따라 조정됩니다. 선택적 필드는 타입 레벨에서 표현되며, 해당 상태에 접근하기 전에 일반적인 TypeScript 검사를 통해 해당 필드의 존재 여부를 확인해야 합니다.
신호 형식 생성 및 결합 실습
시그널을 사용하여 폼을 구축하려면 먼저 로그인 폼과 같이 도메인 모델을 나타내는 쓰기 가능한 시그널을 정의해야 합니다. email password 또는 상점에서 제공하는 복잡한 Flight 엔티티. 이 모델은 단순 신호일 수도 있고, 읽기 전용 저장소의 데이터를 미러링하면서 로컬 편집도 허용하는 경우 연결된 신호일 수도 있습니다.
모델을 얻으면 전화를 겁니다. form(model, schemaOrBuilder) 에 @angular/forms/signals여기서 두 번째 인수는 형식화된 경로 객체를 받는 인라인 함수이거나, 또는 로 생성된 재사용 가능한 스키마일 수 있습니다. schema<T>() 돕는 사람. 이 빌더 내부에서 각 필드에 대한 유효성 검사기, 조건부 규칙, 디바운싱, 비활성화/숨김/읽기 전용 로직 및 메타데이터를 구성할 수 있습니다.
템플릿에서, 디렉티브는 여러분의 보편적인 진입점입니다. <input ="loginForm.email" /> or <input type="number" ="flightForm.id" /> DOM 컨트롤의 값을 기본 필드에 자동으로 연결하여 항상 두 값을 동기화 상태로 유지합니다. 숫자 입력의 경우, 반드시 다음을 사용해야 합니다. type="number" 따라서 Signal Forms는 DOM의 문자열 표현과 모델의 숫자 표현 간의 변환을 투명하게 수행할 수 있습니다.
필드 상태를 읽으려면 필드 노드를 함수처럼 호출하면 됩니다. 예를 들어, flightForm.from().errors() 현재 유효성 검사 오류 목록에 액세스하려면, 또는 flightForm.from().dirty() 사용자가 해당 필드를 수정했는지 확인하기 위해서입니다. 이러한 값들은 신호이므로 OnPush 및 영역 없는 설정과 완벽하게 통합됩니다. Angular는 실제로 이러한 신호에 의존하는 부분만 다시 렌더링합니다.
다음 기능을 사용하여 단일 필드 또는 전체 양식을 초기화할 수 있습니다. reset()이 함수는 상호 작용 상태(터치됨, 더티됨)를 지우고, 새 객체를 전달하는 경우 선택적으로 값을 재설정합니다. 인수 없이, reset() 값은 그대로 두되 상태를 정리하여 현재 데이터를 유지하면서 UI가 새 폼처럼 동작하도록 합니다.
유효성 검사기: 내장, 사용자 지정, 조건부 및 비동기
Signal Forms는 유효성 검사를 위한 새롭고 보다 선언적인 접근 방식을 도입하여, 각 컨트롤 정의에 유효성 검사기를 분산시키는 대신 중앙 스키마 함수에서 규칙을 정의할 수 있도록 합니다. 이 라이브러리에는 다음과 같은 내장 도우미 기능이 포함되어 있습니다. required, min, max, minLength, maxLength, pattern email이 함수는 필드 경로와 사용자에게 표시되는 메시지를 포함한 선택적 옵션 객체를 사용하여 호출합니다.
예를 들어, 다음과 같이 전화할 수 있습니다. required(login.email, { message: 'Email is mandatory' }) email(login.email) 스키마 빌더 내부에 있으며, 이러한 유효성 검사기는 필드 상태를 자동으로 데코레이션합니다. ValidationError 규칙이 적용되지 않을 때마다 항목이 추가됩니다. 각각의 오류는 다음과 같은 결과를 초래할 수 있습니다. kind 문자열과 선택적 추가 데이터(최소값, 패턴 또는 원격 오류 정보 등)를 포함하여 UI에서 일관된 메시지를 표시할 수 있습니다.
사용자 지정 유효성 검사기는 다음을 사용하여 생성됩니다. validate() 단일 필드의 경우 또는 validateTree() 다중 필드 및 트리 레벨 유효성 검사를 위해 사용되며, 다음과 같은 헬퍼를 제공하는 컨텍스트 객체를 받습니다. value(), valueOf(path), state stateOf(path). 유효성 검사기 내부에서는 하나 또는 여러 필드를 동기적으로 검사하고 결과를 반환할 수 있습니다. undefined / null 성공적인 경우 단일 ValidationError 객체를 반환하고, 더 복잡한 상황에서는 오류 배열을 반환합니다.
유효성 검사기는 반응형 컨텍스트 내에서 실행되므로 Signal Forms는 유효성 검사 중에 읽는 모든 신호를 자동으로 추적하고 해당 유효성 검사기가 연결된 기본 필드뿐만 아니라 종속성 중 하나라도 변경될 때마다 해당 유효성 검사기를 다시 실행합니다. 이는 비밀번호 일치와 같은 필드 간 규칙에 정확히 필요한 것입니다. 비교할 때 value() confirmPassword를 사용하여 valueOf(password)두 필드 중 하나라도 변경하면 수동 구독 없이 재검증이 자동으로 실행됩니다.
성능 측면에서 볼 때, 유효성 검사기에서 읽어들이는 내용에 신중해야 합니다. 전체 폼이나 트리 상태를 읽어들이면 변경될 때마다 재실행이 발생하기 때문입니다. 대신, 재계산을 간결하고 예측 가능하게 유지하기 위해 실제로 필요한 최소한의 신호만 읽어들이도록 하세요. 이 반응형 의존성 추적 기능은 기존 모델(수동으로 호출해야 했던 모델)과 비교했을 때 가장 강력하면서도 미묘한 차이점 중 하나입니다. updateValueAndValidity() 관련 컨트롤이 변경될 때 검사를 전파합니다.
고급 유효성 검사: Zod, 표준 스키마 및 비동기 HTTP 검사
Signal Forms는 Zod와 같이 새롭게 부상하는 표준 스키마 사양을 따르는 외부 스키마 라이브러리와 직접 통합할 수 있으므로 기존 서버 측 또는 공유 유효성 검사 로직을 재사용할 수 있습니다. 와 validateStandardSchema(someZodSchema) Zod 스키마를 폼에 연결하여 폼 유효성 검사 파이프라인의 일부로 실행할 수 있습니다.
비동기 유효성 검사는 다음을 기반으로 합니다. validateAsync 그리고 전문적인 validateHttp 이 헬퍼는 컴퓨팅 매개변수의 전체 수명 주기를 처리하고, 리소스 기반 요청을 발행하고, 성공 응답을 ValidationErrors로 매핑하고, 실패를 적절하게 처리합니다. 일반적인 패턴은 HTTP 요청을 다음으로부터 도출하는 것입니다. ctx.value() 필드(예: 사용자 이름 또는 도시 이름)를 선택한 다음 사용합니다. onSuccess 백엔드에서 잘못된 데이터가 감지될 경우 "공항을 찾을 수 없음"과 같은 도메인별 오류를 보고합니다.
비동기 유효성 검사기가 대기 중인 동안 필드의 pending() 신호가 참이 되면 템플릿에서 이를 사용하여 로딩 표시기를 표시하거나 제출을 일시적으로 비활성화할 수 있습니다. 무엇보다 중요한 것은 비동기 유효성 검사기는 모든 동기 유효성 검사기가 통과한 후에만 실행되므로 기본적인 필수 입력이나 패턴 검사가 이미 실패한 상태에서 API에 요청을 폭주시키는 것을 방지할 수 있다는 점입니다.
일반적인 REST 호출의 경우 validateHttp 사용하기가 더 쉽습니다. 요청 구성 객체를 반환하기만 하면 라이브러리가 자동으로 구성해 주기 때문입니다. HttpResource 내부적으로는 그렇지만, 좀 더 특수한 설정이나 RxJS 기반 시나리오의 경우에는 아래로 스크롤하면 됩니다. validateAsync 그리고 통합하다 rxResource 또는 기타 사용자 정의 리소스 추상화. 어쨌든 비동기 유효성 검사는 동기 유효성 검사기와 동일한 오류 및 상태 모델에 깔끔하게 들어맞으므로 UI에서 이를 다르게 처리할 필요가 없습니다.
조건부 규칙, 비활성화/숨겨진 필드 및 메타데이터
실제 양식에서는 특정 조건에서만 특정 필드가 필요한 경우가 많은데, Signal Forms는 다음과 같은 다양한 조건부 도우미 기능을 통해 이를 해결합니다. applyWhen, applyWhenValue예산 및 when 개별 검증자에 대한 옵션. 예를 들어, 특정 결제 하위 섹션에 전용 스키마를 적용하려면 다음과 같은 조건이 충족되어야 합니다. paymentMethod "카드"와 같거나, 강제합니다. delay 그리고 그 최소값은 다음과 같은 경우에만 해당됩니다. delayed 플래그가 맞습니다.
The applyWhenValue 헬퍼는 부모 객체의 축소된 값을 술어에 전달하므로 특히 편리합니다. 이를 통해 타입 가드를 수행하고 판별된 공용체 타입에 따라 다른 스키마를 활성화할 수 있습니다. 이 접근 방식을 사용하면 모든 규칙을 한 곳에 모아두고 타입 안전성을 유지하면서 사용자 선택에 따라 구조 자체가 변경되는 양식을 모델링할 수 있습니다.
유효성 검사 외에도, 필드를 비활성화, 숨김 또는 읽기 전용으로 설정하는 것을 선언적으로 제어할 수 있습니다. disabled, hidden readonly 스키마 내의 함수들은 각각 컨텍스트 상태에 대한 술어를 인수로 받을 수 있습니다. 비활성화된 필드는 상위 필드의 유효성 검사 및 오류 계산에서 제외되는 반면, 숨겨진 필드는 오류가 있더라도 상위 필드를 무효화하지 않으며, 읽기 전용 필드는 사용자가 수정할 수 없으므로 유효성 검사를 건너뜁니다.
재미있게, disabled() 이 필드는 부울 값뿐만 아니라 이유 문자열도 반환할 수 있으며, 모든 활성 이유는 해당 필드를 통해 노출됩니다. disabledReasons() 디버깅 또는 UI 설명을 위한 신호입니다. 이를 통해 필드가 현재 잠겨 있는 이유를 더욱 풍부하게 전달할 수 있으며, 특히 복잡한 워크플로 또는 관리자 인터페이스에서 유용합니다.
Signal Forms는 또한 헬퍼를 사용하여 메타데이터 키를 정의할 수 있는 강력한 메타데이터 시스템을 제공합니다. createMetadataKey, orMetadataKey, andMetadataKey or listMetadataKey그런 다음 다음을 사용하여 필드에 메타데이터를 첨부합니다. metadata() 기능. 소비자는 다음을 통해 이러한 메타데이터 값을 읽을 수 있습니다. fieldState.metadata(SOME_KEY)이 함수는 키가 집계형인지 여부에 따라 직접 값 또는 신호를 반환하므로 필수 플래그, 최소/최대 길이 또는 도메인별 힌트와 같은 기대치를 나타내는 재사용 가능한 구성 요소를 만들 수 있습니다.
재사용 가능한 스키마, 하위 형식 및 복잡한 객체 그래프
폼이 커질수록 여러 곳에서 유효성 검사 로직을 반복하는 것은 유지 관리 측면에서 악몽이 되므로, Signal Forms는 재사용 가능한 스키마를 추출하도록 권장합니다. schema<T>() 그리고 그것들을 다음과 같이 작곡합니다. apply applyEach. 예를 들어, 다음과 같이 정의할 수 있습니다. addressSchema 필수적인 거리, 도시 및 우편번호 패턴을 적용한 다음, 앱에서 주소를 처리하는 모든 곳에서 해당 패턴을 재사용하세요.
최상위 수준에서 기본 폼 스키마는 이러한 하위 스키마를 가져와 billingAddress, shippingAddress 및 contact와 같은 중첩된 개체에 적용하거나 사용할 수 있습니다. applyEach 주소 또는 가격 배열의 각 요소를 대상으로 지정합니다. 이 패턴은 스키마를 작고 집중적이며 테스트하기 쉽게 유지하면서 해당 도메인 유형을 사용하는 모든 양식에서 일관된 동작을 보장합니다.
템플릿 측면에서 복잡한 형태는 FieldTree의 일부를 자식 구성 요소에 전달함으로써 자연스럽게 하위 형태들로 분해됩니다. @Input() 유형의 FieldTree<T>. 부모님 중 한 분이 돌아가실 수도 있습니다. flightForm.aircraft 에 <app-aircraft> 구성 요소 또는 flightForm.prices 에 <app-prices> 각 하위 구성 요소가 전역 시그널 폼 상태에 참여하면서도 하위 섹션을 독립적으로 렌더링하고 유효성을 검사할 수 있도록 합니다.
가격과 같은 배열의 경우 FieldTree 배열을 순회하여 행을 렌더링합니다.@for(price of priceForms; track price)), 각 중첩 필드를 바인딩합니다. ="price.amount"또한 선택적으로 각 행에 대한 오류 요약을 표시할 수 있습니다. price().errorSummary(). 새 행을 추가하는 것은 기본 모델 배열 신호를 새 요소로 업데이트하는 것만큼 간단하며, 그러면 Angular가 자동으로 FieldTree를 확장하고 템플릿 바인딩이 응답합니다.
배열 자체에 유효성 검사기를 정의할 수도 있습니다. 예를 들어, 유효성 검사기에서 현재 배열 값을 반복하고 중복이 감지되면 적절한 ValidationError를 반환하여 가격 행 전체에서 항공편 등급의 고유성을 강제할 수 있습니다. 이러한 어레이 수준 오류는 어레이 노드에서 표시되며, 테이블 위의 공유 영역이나 관련 그룹 옆에 표시될 수 있습니다.
ControlValueAccessor를 사용하지 않는 필드 지시문 통합 및 사용자 지정 컨트롤
Signal Forms에서 가장 만족스러운 편의성 개선 사항 중 하나는 사용자 정의 컨트롤의 간소화입니다. 장황한 ControlValueAccessor 인터페이스를 구현하고 NG_VALUE_ACCESSOR 프로바이더를 등록하는 대신, 간단한 간소화된 사용자 정의 컨트롤만 구현하면 됩니다. FormValueControl<T> or FormCheckboxControl 계약. 최소한 당신은 다음을 노출하게 됩니다. value 모델 신호, 그리고 선택적으로 다음과 같은 추가 입력 disabled, errors, touched, invalid, required or name.
The 지시문은 이러한 인터페이스를 구현하는 구성 요소 또는 지시문을 자동으로 감지하고 적절한 폼 상태 신호를 연결하여 컨트롤의 상태를 유지합니다. value 폼 필드와 동기화된 신호를 보내 터치/변경 정보를 다시 전달합니다. 이렇게 하면 사용자 지정 입력 구성 요소가 몇 줄로 줄어들며, 일반적으로 바인딩만 하면 됩니다. value() 근본적인 것으로 <input> 그리고 통화하기 위해 사건들을 듣고 있습니다. value.set(...).
체크박스의 경우, FormCheckboxControl ~을 사용하다 checked 모델 신호 대신 value이는 체크박스가 일반적으로 부울 값이나 멤버십 상태를 제어하는 영역을 반영하며, 필드 지시문은 부울 필드 값을 매핑하는 구체적인 방법을 처리합니다. checked 플래그. 이렇게 하면 HTML 의미론을 준수하면서도 정신적 모델의 일관성을 유지할 수 있습니다.
동일한 패턴을 속성 지시문을 통해서도 적용할 수 있습니다. 토착 요소이를 통해 디렉티브에 FormValueControl을 구현하고 호스트 바인딩을 사용하여 표준 입력에 대한 동작을 래핑할 수 있습니다. , (input) (blur). 모든 경우에 있어, 더 이상 영역 후크나 수동 onChange/onTouched 콜백에 대해 생각할 필요가 없습니다. 신호를 조작하기만 하면 나머지는 라이브러리가 처리합니다.
템플릿 유형 검사가 훨씬 더 엄격해졌습니다. 만약 실수로 숫자 필드를 텍스트 전용 컴포넌트에 바인딩했는데 해당 컴포넌트가 텍스트 필드만 기대하는 경우 FieldTree<string>TypeScript는 템플릿 바인딩에서 직접 타입 오류를 보고하여 불일치를 조기에 발견하고 미묘한 런타임 문제를 방지합니다. 이러한 추가적인 안전 장치는 Angular 폼에서 이 정도 수준의 완성도를 갖춘 적이 없었던 기능입니다.
다음을 사용하여 마이그레이션 compatForm()제출 흐름 및 디바운싱
Signal Forms는 현실을 인지하고 있습니다. 많은 코드베이스가 반응형 폼에 크게 의존하고 있기 때문에, 이 라이브러리는 반응형 폼 기능을 기본적으로 제공합니다. compatForm() 이 함수는 일반 값과 기존 FormControl 인스턴스를 모두 포함하는 객체 그래프를 래핑할 수 있도록 해줍니다. 호환 폼은 일반 시그널 폼 노드처럼 동작하지만 내부적으로는 래핑된 폼 컨트롤과 동기화되는 필드를 제공합니다. 여기에는 값, 유효성, 터치됨, 변경됨 및 오류 상태가 포함됩니다.
전화 할 때 myForm.age().value() 호환되는 양식에서 age FormControl에서 가져온 값의 경우, FormControl 자체가 아닌 기본 데이터 유형(예: 숫자)을 가져오지만, 실제 FormControl에는 여전히 접근할 수 있습니다. myForm.age().control() 기존 API를 호출해야 하는 경우. 변경 사항은 양방향으로 전파됩니다. 폼 필드를 통해 값을 설정하면 컨트롤이 업데이트되고, 함수를 호출하면 해당 컨트롤이 업데이트됩니다. setValue() FormControl을 업데이트하면 Signal Form 뷰가 업데이트됩니다.
기존 FormControl의 유효성 검사는 그대로 유지되며, 해당 오류는 Signal Form 상태에 반영되어 템플릿이 일관되게 작동할 수 있도록 합니다. valid() errors() 출신에 관계없이. 한 가지 중요한 제한 사항은 새로운 신호 스타일 규칙(예: )을 첨부할 수 없다는 것입니다. required() 시그널 API에서 직접 호환성 래핑된 컨트롤로 전달됩니다. 시스템 충돌을 방지하기 위해 해당 컨트롤은 원래의 Validator 설정을 유지해야 합니다.
신호 양식 제출 절차가 간소화되었습니다. submit(form, action) 도우미모든 필드를 터치된 것으로 표시하고, 양식 유효성을 확인하고, 설정합니다. submitting() 플래그를 지정한 다음 폼이 유효한 경우에만 비동기 작업을 호출합니다. 해당 액션은 폼 상태를 수신하며, 이를 사용하여 API 호출을 수행할 수 있습니다. form().value()또한 선택적으로 라이브러리가 관련 필드에 첨부할 하나 이상의 유효성 검사 오류를 반환합니다.
제출 과정에서 제출 버튼을 쉽게 비활성화할 수 있습니다. ="myForm().submitting()" 또한 적절한 로딩 텍스트를 표시하고, 제출 플래그가 하위 노드로 전달되어 필요한 경우 하위 노드가 자체 UI 상태를 조정할 수 있도록 합니다. 작업이 완료되면 Signal Forms는 제출을 취소하고 반환된 서버 오류를 적용하여 백엔드 유효성 검사를 클라이언트 측 규칙과 깔끔하게 통합합니다.
검색 필드와 같이 성능에 민감한 입력이나 모든 키 입력이 모델을 즉시 업데이트하거나 비동기 유효성 검사를 트리거하지 않도록 하려는 경우에는 debounce() 헬퍼를 사용하면 값 전파를 지연시킬 수 있습니다. 디바운싱은 루트 수준 또는 필드별로 적용할 수 있으며, 밀리초 단위의 타임아웃을 지정하거나 컨텍스트와 중단 신호를 수신하는 사용자 지정 디바운서 함수를 전달하여 보류 중인 타이머를 취소할 수 있습니다.
디바운싱 규칙은 트리를 따라 상속되므로 부모 구조에서 설정하면 자식 구조에서 자체적으로 재정의하지 않는 한 자식 구조에 영향을 미칩니다. 이는 사용자가 입력을 멈춘 후에만 전체 필터 객체가 업데이트되어야 하는 검색 양식에 유용합니다. 유효하고 디바운스된 값에 대해서만 실행되는 비동기 유효성 검사기와 결합하면 API와의 불필요한 통신을 방지하는 효율적인 UI를 구현할 수 있습니다.
Angular 21 Signal Forms는 폼 처리를 통합된 Signal 기반 환경으로 전환하여 모델, 유효성 검사 로직 및 UI를 긴밀하게 정렬하면서도 선언적이고 타입 안정성을 유지함으로써 간단한 로그인 화면부터 유효성 검사가 복잡한 엔터프라이즈 워크플로까지 모든 것을 더 쉽게 구축하고, 이해하고, 시간이 지남에 따라 발전시킬 수 있도록 합니다.