You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular嵌套响应式表单数组增删复制异常及联动下拉同步问题求助

Angular嵌套响应式表单数组复制与级联下拉同步问题

我需要复制一个Angular嵌套响应式表单数组,但目前只能复制数组的一部分。给代码加上用ngModel实现的级联下拉框后,发现新增数组时所有下拉选择会同步变化,我知道这和模型有关,但找不到具体问题。现在只有文件输入框能正常工作,其他字段显示异常。

组件代码

import 'zone.js/dist/zone';
import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
import { bootstrapApplication } from '@angular/platform-browser';
import {
  FormArray,
  FormBuilder,
  FormControl,
  FormGroup,
  FormsModule,
  ReactiveFormsModule,
  Validators,
} from '@angular/forms';

@Component({
  selector: 'my-app',
  standalone: true,
  imports: [CommonModule, FormsModule, ReactiveFormsModule],
  templateUrl: 'main.html',
})
export class App {
  selectedCategoryList: String = "--Choose Category--";

    categoryList: Array<any> = [
    {
        name: "Test One",
        subCategoryList: [
            {
                typeList: [
                    ""
                ],
                name: "Test 1"
            },
            {
                typeList: [
                    ""
                ],
                name: "Test 1.1"
            },
            {
                typeList: [
                    ""
                ],
                name: "Test 2.2"
            }
        ]
    },
    {
        name: "Test Two",
        subCategoryList: [
            {
                typeList: [
                    ""
                ],
                name: "Test 2"
            },
            {
                typeList: [
                    ""
                ],
                name: "Test 2.1"
            },
            {
                typeList: [
                    ""
                ],
                name: "Test 2.2"
            }
        ]
    },
    {
        name: "Test Three",
        subCategoryList: [
            {
                typeList: [
                    ""
                ],
                name: "Test 3"
            }
        ]
    }
];

selectedCountry: String = "--Choose Document Category--";

subCategoryList: Array<any> = [];
typeList: Array<any> = [];

  form!: FormGroup;

  constructor(private fb: FormBuilder) {}

  documentForm = this.fb.group({
    appCode: ['123'],
    accountType: [''],
    emailId: ['test@aol.com'],
    IDV: [''],
    envelopeRequest: this.fb.group({
      documents: this.fb.array([]),
    }),
  });

  ngOnInit() {
    // this.form = this.fb.group({
    //   documents: this.fb.array([]),
    // });
    this.initDocument();
  }

  changeCategoryList(category: any) {
    this.subCategoryList = this.categoryList.find((cat: any) => cat.name == category.target.value).subCategoryList;
  }
  
  changeSubCategoryList(subList: any) {
    this.typeList = this.categoryList.find((cat: any) => cat.name == this.selectedCountry).subCategoryList.find((stat: any) => stat.name == subList.target.value).typeList;
  }

  initDocument() {
    this.documents.push(this.newDocument());
    let documentIndex = this.documents.length - 1;
    this.newDocumentFieldGroup(documentIndex);

    //console.log(this.documentFields(0).controls.length);
  }

  newDocument() {
    return this.fb.group({
      name: new FormControl(''),
      documentId: new FormControl(''),
      documentFields: this.fb.array([]),
    });
  }

  newDocumentFieldGroup(comIndex: number) {
    this.documentFields(comIndex).push(this.newDocumentFields());

    this.documentFields(comIndex).push(
      this.newDocumentFields('documentSubCategory')
    );
  }

  newDocumentFields(name = 'documentCategory') {
    return this.fb.group({
      name: new FormControl(name),
      value: new FormControl(''),
    });
  }

  get documents() {
    // Problem was from here, should use `documentForm` --> envelopeRequest --> documents
    return this.documentForm.controls.envelopeRequest.controls
      .documents as FormArray;
  }

  documentFields(comIndex: number) {
    return this.documents.controls[`${comIndex}`].get(
      'documentFields'
    ) as FormArray;
  }

  documentFieldsIndexes(comIndex: number) {
    return Array(this.documentFields(comIndex).controls.length / 2)
      .fill(0)
      .map((x, i) => i * 2);
  }

  submit() {
    console.log(this.documentForm.value);
  }
}

bootstrapApplication(App);

HTML代码

<form [formGroup]="documentForm" (ngSubmit)="submit()">
  
  <ng-container formGroupName="envelopeRequest">
    <button (click)='initDocument()'>Add Document</button>
    <ng-container formArrayName="documents">
      <ng-container
        *ngFor="let control of documents.controls; let comIndex=index"
      >
        <ng-container [formGroupName]="comIndex">
          <div class="row justify-content-start mb-3">
            <div class="col-md-1">
              {{comIndex}}
              <input
                type="hidden"
                id="fname"
                name="fname"
                formControlName="documentId"
              />
              <label for="formFile" class="col-form-label">File:</label>
            </div>
            <div class="col-md-6">
              <input
                class="form-control"
                type="file"
                id="file"
                name="file"
                formControlName="name"
              />
            </div>
          </div>
          <ng-container formArrayName="documentFields">
            <ng-container
              *ngFor="let skillIndex of documentFieldsIndexes(comIndex);"
            >
              <div class="row mb-3">
                <label class="col-sm-1 col-form-label">Category:</label>
                <div class="col-md-2">
                  <ng-container [formGroupName]="skillIndex">
                    <select id="" class="form-select" formControlName="value" [(ngModel)]= "selectedCategoryList" (change)="changeCategoryList($event)">
                      <option selected>Select</option>
                      <option *ngFor="let c of categoryList">
                        {{c.name}}
                      </option>
                    </select>
                  </ng-container>
                </div>

                <label class="col-auto col-form-label">Sub-Category:</label>
                <div class="col-md-2">
                  <ng-container [formGroupName]="skillIndex + 1">
                    <select id="" class="form-select" formControlName="value" (change)="changeSubCategoryList($event)">
                      <option selected>Select</option>
                      <option *ngFor="let s of subCategoryList">{{s.name}}</option>
                    </select>
                  </ng-container>
                </div>
              </div>
            </ng-container>
          </ng-container>
        </ng-container>
      </ng-container>
    </ng-container>
  </ng-container>

  <button type="submit">Submit</button>
</form>
<pre>{{this.documentForm.value | json }}

内容的提问来源于stack exchange,提问作者fearless924

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 14:02:02