Вопрос или проблема
Поле ввода не отображается с внешним видом mat-form-field до щелчка внутри, когда используется formGroupName с FormArray.
Смотрите пример:
TS:
formMain = this.fb.group({
details: this.fb.array([
new FormGroup({
label: new FormControl(''),
description: new FormControl(''),
}),
]),
});
get detailsFormArray() {
return this.formMain.controls.details as FormArray;
}
addDetails() {
this.detailsFormArray.push(this.fb.control(''));
}
}
HTML:
<form [formGroup]="formMain">
<div formArrayName="details">
<div
*ngFor="let detail of detailsFormArray.controls; index as i"
[formGroupName]="i"
>
<mat-form-field appearance="fill">
<mat-label>Этикетка детали</mat-label>
<input id="detail-label" matInput type="text" formControlName="label" />
</mat-form-field>
<mat-form-field appearance="fill">
<mat-label>Описание детали</mat-label>
<input
id="detail-description"
matInput
type="text"
formControlName="description"
/>
</mat-form-field>
</div>
</div>
</form>
<br />
<button type="button" (click)="addDetails()">+ Добавить детали</button>
После нажатия на Добавить детали и до нажатия на форму:
и
Есть ли решение этой проблемы?
Вы неправильно добавляете экземпляр FormGroup
в details
FormArray
. В настоящее время вы добавляете экземпляр FormControl
.
Рекомендуем написать общую функцию для создания экземпляра FormGroup
.
formMain = this.fb.group({
details: this.fb.array([this.addDetailsFormGroup()]),
});
addDetails() {
this.detailsFormArray.push(this.addDetailsFormGroup());
}
addDetailsFormGroup() {
return new FormGroup({
label: new FormControl(''),
description: new FormControl(''),
});
}
Ответ или решение
Проблема, с которой вы столкнулись, связана с неправильным добавлением экземпляра FormGroup
в массив FormArray
. В текущей реализации вы добавляете экземпляр FormControl
, что приводит к неправильному отображению полей ввода внутри компонента <mat-form-field>
.
Для корректного отображения элементов формы, вам необходимо создать и добавить экземпляр FormGroup
, который будет содержать необходимые контролы (label
и description
). Я рекомендую создать вспомогательную функцию, которая будет возвращать новый экземпляр FormGroup
с нужными контроллерами. Ниже приведен исправленный код:
TypeScript (TS)
import { Component } from '@angular/core';
import { FormBuilder, FormControl, FormGroup, FormArray } from '@angular/forms';
@Component({
selector: 'app-your-component',
templateUrl: './your-component.component.html',
styleUrls: ['./your-component.component.css']
})
export class YourComponent {
formMain = this.fb.group({
details: this.fb.array([this.createDetailsFormGroup()]),
});
constructor(private fb: FormBuilder) {}
get detailsFormArray(): FormArray {
return this.formMain.get('details') as FormArray;
}
addDetails() {
this.detailsFormArray.push(this.createDetailsFormGroup());
}
private createDetailsFormGroup(): FormGroup {
return this.fb.group({
label: new FormControl(''),
description: new FormControl(''),
});
}
}
HTML
<form [formGroup]="formMain">
<div formArrayName="details">
<div *ngFor="let detail of detailsFormArray.controls; index as i" [formGroupName]="i">
<mat-form-field appearance="fill">
<mat-label>Label of a detail</mat-label>
<input id="detail-label" matInput type="text" formControlName="label" />
</mat-form-field>
<mat-form-field appearance="fill">
<mat-label>Description of a detail</mat-label>
<input id="detail-description" matInput type="text" formControlName="description" />
</mat-form-field>
</div>
</div>
</form>
<br />
<button type="button" (click)="addDetails()">+ Add Details</button>
Объяснение
-
Создание экземпляра
FormGroup
: Мы создали методcreateDetailsFormGroup()
, который возвращает новыйFormGroup
с контроламиlabel
иdescription
. Это позволяет вам легко управлять структурой формы. -
Исправление метода
addDetails()
: Теперь данный метод вызываетcreateDetailsFormGroup()
, что гарантирует, что в массивFormArray
добавляется правильный экземплярFormGroup
.
Заключение
С этими изменениями ваше поле ввода будет корректно отображаться с нужным стилем и поведением при добавлении новых деталей. Если вы хотите протестировать это решение, вы можете использовать предоставленную ссылку на StackBlitz, чтобы быстро понять, как все работает.
Если у вас есть дополнительные вопросы или необходима помощь, не стесняйтесь обращаться!