Angular FormGroup внутри FormArray с использованием нового потока управления

У меня есть реактивная угловая форма, которая имеет 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"> изменит контекст для элементов управления внутри него. Это не.

Может ли кто-нибудь помочь мне понять, как связать элементы управления внутри массива форм, учитывая, что внутри этого массива будет несколько групп форм «разделов», которые должны отображать соответствующие элементы управления?

Прежде чем я попытаюсь ответить на вопрос, я хотел бы отметить, что в директиве formGroupName в коде, которым вы поделились (forGroupName в вашем коде), есть опечатка. Я просто хочу убедиться, что это не источник проблемы, прежде чем писать правильный ответ?

Tibère B. 29.04.2024 17:42

спасибо, проблема была не в опечатке

J King 29.04.2024 17:47
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Angular и React для вашего проекта веб-разработки?
Angular и React для вашего проекта веб-разработки?
Когда дело доходит до веб-разработки, выбор правильного front-end фреймворка имеет решающее значение. Angular и React - два самых популярных...
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Мы провели Twitter Space, обсудив несколько проблем, связанных с последними дополнениями в Angular. Также прошла Angular Tiny Conf с 25 докладами.
Угловой продивер
Угловой продивер
Оригинал этой статьи на турецком языке. ChatGPT используется только для перевода на английский язык.
Мое недавнее углубление в Angular
Мое недавнее углубление в Angular
Недавно я провел некоторое время, изучая фреймворк Angular, и я хотел поделиться своим опытом со всеми вами. Как человек, который любит глубоко...
Освоение Observables и Subjects в Rxjs:
Освоение Observables и Subjects в Rxjs:
Давайте начнем с основ и постепенно перейдем к более продвинутым концепциям в RxJS в Angular
4
2
83
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Вам необходимо определить 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]),
  });
}

Демо-версия Stackblitz

отлично, спасибо, я только что добавил formArrayName = "sections", но пропустил индекс, являющийся formGroupName. Теперь это работает!

J King 29.04.2024 17:47

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

Переключение между информацией о карте
Как я могу показать только одно предупреждение о нескольких удалениях в angular?
Для сегмента не могут быть установлены общедоступные списки ACL с включенным BlockPublicAccess
ОШИБКА [ExceptionsHandler] Неизвестная стратегия аутентификации «jwt». Ошибка: неизвестная стратегия аутентификации «jwt»
Невозможно получить новейший токен до загрузки компонента в angular
Как исправить «Тип «void» не может быть назначен типу «Function» в VueJS?
Angular 17 – Как добавить errorStateMatcher в массив форм, но тот, который пересекает группы форм по последовательным индексам
Зачем писать возвращаемый тип защиты типа как «это (…) и это» в TypeScript?
Как временно изменить значение цветовой переменной в компоненте в Ionic 8 с помощью нового обновления цветовой палитры?
Как создать универсальный компонент формы в Next.js 14 с помощью TypeScript и формы реагирования?