【问题标题】: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
  • 您是否检查过其他问题,例如:stackoverflow.com/q/59553622/5468463stackoverflow.com/q/59588933/5468463。有很多
  • 是的,我确实检查了这个问题。它似乎没有解决我的问题。当我尝试访问控件时,它说控件未定义。

标签: angular angular-reactive-forms angular2-forms angular-forms formarray


【解决方案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

    【讨论】:

    • 非常感谢。它解决了这个问题。所以我的理解是我没有推动表单控件(用于联系人数组)。对吗?
    • 是的,正确。你能接受并投票吗,它也会帮助其他人
    猜你喜欢
    • 2020-10-05
    • 1970-01-01
    • 1970-01-01
    • 2021-03-25
    • 2017-11-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多