FormBuilder 在 ng14 中具有强类型表单

问题描述 投票:0回答:4

我有以下表格:

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

angular angular-reactive-forms formbuilder angular14
4个回答
8
投票

对于 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;}>

3
投票

我有一个针对这个问题的解决方案,我为此编写了一些类型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>;
    }>>;
}>

2
投票

@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


0
投票

顺便说一句,对于不可为空(必需)的表单,请使用

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),
})
© www.soinside.com 2019 - 2024. All rights reserved.