如何修补嵌套表单数组?

Posted

技术标签:

【中文标题】如何修补嵌套表单数组?【英文标题】:How to patch a nested form Array? 【发布时间】:2021-12-02 12:28:51 【问题描述】:

我有来自表单(模态)的数据,我必须将其修补到另一个表单(折叠)中。 这是数据的来源。

formInitializer() 
    this.agrmntsForm = this.formBuilder.group(
      sales_price: new FormControl(''),
      closing_cost_support: new FormControl(''),
      financing: new FormControl(''),
      contract_date: new FormControl(''),
      inspection_period: new FormControl(''),
      closing_date: new FormControl(''),
      contacts: this.formBuilder.array([]),
    );
   

这是我试图将数据修补到的表单:

mainFormInitializer() 
    this.mainForm = this.formBuilder.group(
      agreements: this.formBuilder.array([]),
    );
  

目前我正在修补第一个表单(模态)提交的数据。它确实修补了第一个数组,但我很难修补其中的嵌套表单数组。

这是修补表单的代码:

patchControls(formValue) 
    const control = <FormArray>this.mainForm.get('agreements');
    // const control2 = <FormArray>this.mainForm.get('contacts');
    console.log('form here', this.mainForm.controls.contacts);
    for (const obj of formValue) 
      const addrCtrl = this.createAgreementsGroup();
      const contactsCtrl = this.createContactsCtrl();
      addrCtrl.patchValue(obj);
      control.push(addrCtrl);
    
  

我已将代码添加到stackblitz

【问题讨论】:

您是否只想将模型生成的this.agrmntsForm Form Group 添加到this.mainFormagreements 数组中? 是的。模态生成的表单包含agreements(组),它还包含contacts 的数组。我想要我的mainForm 协议数组中的这两件事,以便我获得协议详细信息以及与特定agreement 关联的contacts 您是否检查过其他问题,例如:***.com/q/59553622/5468463 或 ***.com/q/59588933/5468463。有很多 是的,我确实检查了这个问题。它似乎没有解决我的问题。当我尝试访问控件时,它说控件未定义。 【参考方案1】:

删除了一些重复的代码,您需要重新启动 agrmntsForm 而不是仅仅重置,因为如果您添加多个联系人,其值将被重置,但在模型中添加下次协议表单时不会保留联系人数组条目。

在以下示例中,您可以在主窗体中添加/删除联系人

在模板中迭代contacts

<div *ngFor="let contact of getContactFG(agreementIndex);let contactIndex = index" >
    <div [formGroupName]="contactIndex">
        Contact  contactIndex + 1  <br />
            agreement_type :
        <input type="text" formControlName="agreement_type" /><br />
            company
        <input type="text" formControlName="company" /><br />
            email :
        <input type="text" formControlName="email" /><br />
            name:
        <input type="text" formControlName="name" /><br />
            phone_number :
        <input type="text" formControlName="phone_number" /><br />
        <button (click)="removeContact(agreementIndex, contactIndex)">
            Remove Contact
        </button>
    </div>
</div>

mainFormagrementForm 中获取/删除/添加联系人的帮助方法

  ngOnInit() 
    this.initForms();
  

  initForms(): void 
    this.agrmntsForm = this.getNewAgreementFG(0);
    this.mainForm = this.formBuilder.group(
      agreements: this.formBuilder.array([]),
    );
  

  getNewAgreementFG(noOfContacts: number): FormGroup 
    const contactArr = Array.from( length: noOfContacts , (v, i) => i).map(
      (n) => this.createContactsCtrl()
    );
    return this.formBuilder.group(
      sales_price: [null],
      closing_cost_support: [null],
      financing: [null],
      contract_date: [null],
      inspection_period: [null],
      closing_date: [null],
      contacts: this.formBuilder.array(contactArr),
    );
  

  getContactFGByIndex(groupIndex: number): FormArray 
    return (this.agreements().at(groupIndex) as FormGroup).get(
      'contacts'
    ) as FormArray;
  

  addContactsMain(groupIndex: number) 
    this.getContactFGByIndex(groupIndex).push(this.createContactsCtrl());
  

  getContactFG(groupIndex: number): FormGroup[] 
    return this.getContactFGByIndex(groupIndex).controls as FormGroup[];
  

  removeContact(groupIndex: number, contactIndex: number): void 
    this.getContactFGByIndex(groupIndex).removeAt(contactIndex);
  

  onSubmit() 
    this.isAgsVisible = false;
    const agrementFG = this.getNewAgreementFG(
      this.agrmntsForm.getRawValue().contacts.length
    );
    agrementFG.patchValue(this.agrmntsForm.getRawValue());
    this.agreements().push(agrementFG);
  

  deleteAgrContact(contactIndex) 
    this.contactsArr().removeAt(contactIndex);
  

  public agreements(): FormArray 
    return this.mainForm.get('agreements') as FormArray;
   

希望这能解决你所有的问题

Full Angular Demo

【讨论】:

【参考方案2】:

您需要更新以下方法:

createAgreementsGroup(obj) 
 return this.formBuilder.group(
   closing_cost_support: [obj.closing_cost_support],
   closing_date: [obj.closing_date],
   contract_date: [obj.contract_date],
   financing: [obj.financing],
   inspection_period: [obj.inspection_period],
   sales_price: [obj.sales_price],
  contacts: this.formBuilder.array(this.createContactsCtrl(obj.contacts))
 );



createContactsCtrl(data) 
  console.log('contacts', data);
   const formArray = [];

   for(let contact of data)
     formArray.push(
       this.formBuilder.group(
         agreement_type: [contact.agreement_type],
         company: [contact.company],
         email: [contact.email],
         name: [contact.name],
         phone_number: [contact.phone_number],
      )
    );
   
  return formArray;
 

patchControls(data2) 
  const control = <FormArray>this.mainForm.get('agreements');

  for (const obj of data2) 
    const addrCtrl = this.createAgreementsGroup(obj);
    control.push(addrCtrl);
 

查看stackblitz

【讨论】:

非常感谢。它解决了这个问题。所以我的理解是我没有推动表单控件(用于联系人数组)。对吗? 是的,正确。你能接受并投票吗,它也会帮助其他人

以上是关于如何修补嵌套表单数组?的主要内容,如果未能解决你的问题,请参考以下文章

如何在angular2的表单数组中显示嵌套数组数据?

如何使用 angular2 Reactive 表单构建嵌套数组?

如何使用 Postman 表单数据在 Django REST Framework 中发布嵌套数组?

如何使用验证编辑嵌套的反应式表单?

如何在嵌套表单数组中选择all并取消全选?

从 JSON 数据的嵌套表单数组填充表单控件中的值