我有以下表格:
const enum Fields {
FirstName = 'firstName',
LastName = 'lastName'
}
interface FormType {
[Fields.FirstName]: FormControl<string | null>;
[Fields.LastName]: FormControl<string | null>;
}
public form!: FormGroup<FormType>;
this.form = new FormGroup({
[Fields.FirstName]: new FormControl(null, { validators: Validators.required }),
[Fields.LastName]: new FormControl(null, { validators: Validators.required }),
});
使用
enum
是我避免打字错误的习惯。
当我执行
this.form.getRawValue().firstName
时,firstName
的类型被正确定义为 string | null
。但是,我更喜欢使用 FormBuilder
来构建我的表单,但我找不到使用 FormBuilder
翻译上面表单的方法。我试过这个:
this.form = this._fb.group<FormType>({
[Fields.FirstName]: ['', Validators.required],
[Fields.LastName]: ['', Validators.required],
});
我当然可以使用一个简单的
FormGroup
,没有任何类型,但它会达不到目的:p
但是,这甚至不能作为
string | Validators
的推断类型。我尝试了不同的方法但没有成功。
是否可以将 FormBuilder 与强类型表单一起使用?
对于 Formbuilder,您可以提供原始值、控件或装箱值,系统将自动推断类型。
this.form = this._fb.group({
[Fields.FirstName]: ['', Validators.required],
[Fields.LastName]: ['', Validators.required],
});
更新
我们无法传递模型的类型,由于 FormType 需要与 formControl 组合,因此我们需要为每个控件指定 formControl。
this.form = this.fb.group<FormType>({
[Fields.FirstName]: this.fb.control('', Validators.required),
[Fields.LastName]: this.fb.control('', Validators.required),
});
this.form.value //value: Partial<{firstName: string | null;lastName: string | null;}>
我有一个针对这个问题的解决方案,我为此编写了一些类型https://github.com/iamguid/ngx-mf .
例如你可以这样做:
我们定义一些模型:
enum ContactType {
Email,
Telephone,
}
interface IContactModel {
type: ContactType;
contact: string;
}
interface IUserModel {
id: number;
firstName: string;
lastName: string;
nickname: string;
birthday: Date;
contacts: IContactModel[];
}
然后我们定义一些魔法类型,例如:
Type Form = FormModel<IUserModel, { contacts: ['group'] }>
然后我们在表单初始化之前根据我们的模型进行类型:
FormGroup<{
firstName: FormControl<string | null>;
lastName: FormControl<string | null>;
nickname: FormControl<string | null>;
birthday: FormControl<Date | null>;
contacts: FormArray<FormGroup<{
type: FormControl<ContactType | null>;
contact: FormControl<string | null>;
}>>;
}>
@Chelappan小补充:
至少你可以在这里严格给出类型,而不是通过专门引入类型来从提供的值推断。
FormBuilder 示例:
this.form = this.fb.group<FormType>({
[Fields.FirstName]: this.fb.control<string|null>(null, Validators.required),
[Fields.LastName]: this.fb.control<string|null>(null, Validators.required),
});
因此,通过使用像
setValue
这样的表单方法,即使使用 null
初始化,在提供字符串时也不会导致错误
另请参阅:https://angular.io/guide/typed-forms#specifying-an-explicit-type
顺便说一句,对于不可为空(必需)的表单,请使用
nonNullable
中的 FormBuilder
,如下所示:
this.form = this.fb.group<FormType>({
[Fields.FirstName]: this.fb.nonNullable.control<string>('your type here', Validators.required),
[Fields.LastName]: this.fb.nonNullable.control<string>('', Validators.required),
})