Angular Signal Forms 如何绑定 nullable 文本字段?
数据小许
结论
无需调整 tsconfig。description 的类型是 string | null,而原生 <input type="text"> 用空字符串 '' 表示空值,不能直接接收 null。Angular 的 Signal Forms 文档也指出,原生文本控件不支持 null。因此,表单字段应使用 string。如果业务数据需要用 null 表示空描述,可以在表单模型和业务模型之间转换。Angular Signal Forms:Form models
推荐做法:表单使用 string,提交时转换
保留业务实体的 nullable 类型,另行定义适配文本输入框的表单模型:
interface Entity {
name: string;
description: string | null;
}
interface EntityFormModel {
name: string;
description: string;
}
protected readonly entity = signal<Entity>({
name: '',
description: null,
});
protected readonly formModel = signal<EntityFormModel>({
name: '',
description: this.entity().description ?? '',
});
protected readonly form = form(this.formModel, (path) => {
required(path.name);
});
protected submit($event: Event) {
$event.preventDefault();
$event.stopPropagation();
const formValue = this.formModel();
const entity: Entity = {
name: formValue.name,
description: formValue.description === '' ? null : formValue.description,
};
console.log('submit', entity);
}
模板仍然绑定文本字段:
<input id="description" type="text" [field]="form.description">
业务数据中的 null 会转换为表单可显示的 '';提交时,再按业务规则把空字符串转换回 null。如果空字符串和 null 在业务上含义不同,就保留用户输入,不要进行转换。
关于保留 nullable 表单字段
在合适的场景中,Signal Forms 模型可以使用 null,例如由自定义控件整体读写值。但原生输入控件对值类型有各自的要求:文档建议模型类型与实际 UI 控件匹配,原生文本输入框和 <textarea> 都使用字符串作为输入值。Angular Signal Forms:Form model design
不要为了消除错误而关闭 strictNullChecks,也不要直接把 nullable 字段断言为 string。这些做法只会隐藏类型不匹配,无法让原生文本控件支持 null。
备注:内容仅供参考。
