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

Другие вопросы по тегам