关于 angular-forms
面向 Angular 开发表单的技能,介绍 Signal Forms、Reactive Forms 和模板驱动表单的适用场景,并涵盖类型安全与嵌套表单。
主要功能
- 01比较三种表单方式
- 02Signal Forms 类型安全字段访问
- 03Reactive Forms 同步处理与类型安全
- 04构建嵌套表单和 FormArray
适用场景
- 01为新应用选择 Signal Forms
- 02为生产应用实现响应式表单
- 03为简单表单采用模板驱动方式
安装
复制下面的命令,在终端中运行。
$
npx skills add https:/ / github.com/ gentleman-programming/ gentleman-skills --skill angular-forms安装后在 Claude Code 中输入/angular-forms确认已加载。
详细介绍
何时使用哪种表单
| 使用场景 | 建议 |
|---|---|
| 使用信号的新应用 | 信号表单(实验性) |
| 生产环境应用 | 响应式表单 |
| 简单表单 | 模板驱动 |
信号表单(v21+,实验性)
import { form, FormField, required, email } from '@angular/forms/signals';
@Component({
imports: [FormField],
template: `
<form>
<input [formField]="emailField" type="email" />
<input [formField]="passwordField" type="password" />
<button (click)="submit()">Login</button>
</form>
`
})
export class LoginComponent {
readonly loginForm = form({
email: ['', [required, email]],
password: ['', required]
});
readonly emailField = this.loginForm.controls.email;
readonly passwordField = this.loginForm.controls.password;
submit() {
if (this.loginForm.valid()) {
const values = this.loginForm.value();
}
}
}
信号表单的优势
- 自动双向绑定
- 类型安全的字段访问
- 基于 Schema 的验证
- 基于信号构建
响应式表单(生产环境)
import { FormBuilder, Validators, ReactiveFormsModule } from '@angular/forms';
@Component({
imports: [ReactiveFormsModule],
template: `
<form [formGroup]="form" (ngSubmit)="submit()">
<input formControlName="email" type="email" />
<input formControlName="password" type="password" />
<button type="submit" [disabled]="form.invalid">Login</button>
</form>
`
})
export class LoginComponent {
private readonly fb = inject(FormBuilder);
form = this.fb.nonNullable.group({
email: ['', [Validators.required, Validators.email]],
password: ['', [Validators.required, Validators.minLength(8)]],
});
submit() {
if (this.form.valid) {
const { email, password } = this.form.getRawValue();
}
}
}
要点
- 始终使用
fb.nonNullable.group()确保类型安全 - 使用
getRawValue()获取类型化的值 - 响应式表单是同步的(更易于测试)
嵌套表单和 FormArray
form = this.fb.nonNullable.group({
name: [''],
address: this.fb.group({
street: [''],
city: [''],
}),
phones: this.fb.array([this.fb.control('')]),
});
get phones() {
return this.form.get('phones') as FormArray;
}
addPhone() {
this.phones.push(this.fb.control(''));
}
资源
评论
支持 Markdown