ng14中具有强类型表单的FormBuilder

我有以下表格:

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 与强类型表单一起使用?

stack overflow FormBuilder with strongly typed form in ng14
原文答案
author avatar

接受的答案

对于 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>;
    }>>;
}>
作者头像

@Chellappan 小补充:
至少您可以在这里严格给出类型,而不是通过专门引入类型来从提供的值推断。

表单生成器示例:

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