У меня есть реактивная угловая форма, которая имеет formArray групп форм, называемых разделами:
sectionForm = new FormGroup({
title: new FormControl<string>('New Section', {nonNullable: true, validators: [Validators.required]}),
subTitle: new FormControl<string>('section sub title', {nonNullable: true}),
description: new FormControl<string>('description', {nonNullable: true}),
});
sessionForm = new FormGroup({
title: new FormControl<string>('', {nonNullable: true, validators: [Validators.required]}),
subTitle: new FormControl<string>('', {nonNullable: true, validators: [Validators.required]}),
description: new FormControl<string>('', {nonNullable: true, validators: [Validators.required]}),
sections: new FormArray([this.sectionForm])
});
Я использую здесь реактивные формы и хочу создать HTML-форму, соответствующую этой настройке. У меня есть следующий раздел моей формы, который пытается использовать новый поток управления для отображения группы форм разделов внутри массива форм:
<form [formGroup] = "sessionForm" class = "k-form k-form-md">
<fieldset class = "k-form-fieldset">
<!-- other form controls ........ -->
<div cy-data = "session-sections">
@for (section of sessionForm.controls.sections.controls; track $index) {
<div forGroupName = "section">
<kendo-formfield cy-data = "section-title">
<kendo-label [for] = "sectiontitle" text = "Section Title"></kendo-label>
<kendo-textbox
#sectiontitle
class = "text-input"
formControlName = "title"
[clearButton] = "true"
required
></kendo-textbox>
<kendo-formerror>Error:Section Title Required</kendo-formerror>
</kendo-formfield>
<kendo-formfield cy-data = "section-subtitle">
<kendo-label [for] = "sectionsubtitle" text = "Section Sub Title"></kendo-label>
<kendo-textbox
#sectionsubtitle
class = "text-input"
formControlName = "subTitle"
[clearButton] = "true"
required
></kendo-textbox>
<kendo-formerror>Error:Section Sub Title Required</kendo-formerror>
</kendo-formfield>
<kendo-formfield cy-data = "section-description">
<kendo-label [for] = "sectiondescription" text = "Section Description"></kendo-label>
<kendo-textarea
#sectiondescription
class = "text-input"
formControlName = "description"
required
></kendo-textarea>
<kendo-formerror>Error:Section Description Required</kendo-formerror>
</kendo-formfield>
</div>
}
</div>
</fieldset>
</form>
перечисленные выше входные данные, имеющие общее имя с родительской группой форм, привязаны к элементам управления в родительской группе форм, а не к элементам управления внутри массива форм. Поэтому все, что я ввожу в поле «Название раздела», обновляет свойство родительского заголовка.
Я думал, что установка formGroupName в разделе div to <div forGroupName = "section"> изменит контекст для элементов управления внутри него. Это не.
Может ли кто-нибудь помочь мне понять, как связать элементы управления внутри массива форм, учитывая, что внутри этого массива будет несколько групп форм «разделов», которые должны отображать соответствующие элементы управления?
спасибо, проблема была не в опечатке





Вам необходимо определить formArrayName = "sections" над циклом for, чтобы было ясно, что элементы управления принадлежат массиву формы.
Затем для первого элемента внутри цикла for нам нужно установить [formGroupName] = "index", чтобы было ясно, что блок кода принадлежит n-му элементу formGroup массива форм:
...
<div cy-data = "session-sections" formArrayName = "sections">
@for (section of sessionForm.controls.sections.controls;let index = $index; track index) {
<div [formGroupName] = "index">
...
Полный код:
import { Component, ViewChild, ViewEncapsulation } from '@angular/core';
import { FormGroup, FormControl } from '@angular/forms';
import { TextBoxComponent } from '@progress/kendo-angular-inputs';
import { FormArray, ReactiveFormsModule, Validators } from '@angular/forms';
@Component({
selector: 'my-app',
template: `
<pre>{{sessionForm.value | json}}</pre>
<form [formGroup] = "sessionForm" class = "k-form k-form-md">
<fieldset class = "k-form-fieldset">
<!-- other form controls ........ -->
<div cy-data = "session-sections" formArrayName = "sections">
@for (section of sessionForm.controls.sections.controls;let index = $index; track index) {
<div [formGroupName] = "index">
<kendo-formfield cy-data = "section-title">
<kendo-label [for] = "sectiontitle" text = "Section Title"></kendo-label>
<kendo-textbox
#sectiontitle
class = "text-input"
formControlName = "title"
[clearButton] = "true"
required
></kendo-textbox>
<kendo-formerror>Error:Section Title Required</kendo-formerror>
</kendo-formfield>
<kendo-formfield cy-data = "section-subtitle">
<kendo-label [for] = "sectionsubtitle" text = "Section Sub Title"></kendo-label>
<kendo-textbox
#sectionsubtitle
class = "text-input"
formControlName = "subTitle"
[clearButton] = "true"
required
></kendo-textbox>
<kendo-formerror>Error:Section Sub Title Required</kendo-formerror>
</kendo-formfield>
<kendo-formfield cy-data = "section-description">
<kendo-label [for] = "sectiondescription" text = "Section Description"></kendo-label>
<kendo-textarea
#sectiondescription
class = "text-input"
formControlName = "description"
required
></kendo-textarea>
<kendo-formerror>Error:Section Description Required</kendo-formerror>
</kendo-formfield>
</div>
}
</div>
</fieldset>
</form>
`,
encapsulation: ViewEncapsulation.None,
styleUrls: ['./styles.css'],
})
export class AppComponent {
sectionForm = new FormGroup({
title: new FormControl<string>('New Section', {
nonNullable: true,
validators: [Validators.required],
}),
subTitle: new FormControl<string>('section sub title', {
nonNullable: true,
}),
description: new FormControl<string>('description', { nonNullable: true }),
});
sessionForm = new FormGroup({
title: new FormControl<string>('', {
nonNullable: true,
validators: [Validators.required],
}),
subTitle: new FormControl<string>('', {
nonNullable: true,
validators: [Validators.required],
}),
description: new FormControl<string>('', {
nonNullable: true,
validators: [Validators.required],
}),
sections: new FormArray([this.sectionForm]),
});
}
отлично, спасибо, я только что добавил formArrayName = "sections", но пропустил индекс, являющийся formGroupName. Теперь это работает!
Прежде чем я попытаюсь ответить на вопрос, я хотел бы отметить, что в директиве formGroupName в коде, которым вы поделились (forGroupName в вашем коде), есть опечатка. Я просто хочу убедиться, что это не источник проблемы, прежде чем писать правильный ответ?