FormBuilder со строго типизированной формой в ng14
У меня есть следующая форма:
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
. Я пробовал это:
this.form = this._fb.group<FormType>({
[Fields.FirstName]: ['', Validators.required],
[Fields.LastName]: ['', Validators.required],
});
Я мог бы, конечно, использовать простой
FormGroup
без какого-либо типа, но это разрушит цель: p
Однако это даже не работает как предполагаемый тип
string | Validators
. Я пробовал разные вещи без успеха.
Можно ли использовать FormBuilder со строго типизированными формами?
3 ответа
Для Formbuilder вы можете указать необработанное значение, элемент управления или значение в рамке, и тип будет определен автоматически.
this.form = this._fb.group({
[Fields.FirstName]: ['', Validators.required],
[Fields.LastName]: ['', 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