【问题标题】:Angular 2 Forms - How to patchValue on a nested Form Group that contains an array of objectsAngular 2 Forms - 如何在包含对象数组的嵌套表单组上修补值
【发布时间】:2017-03-27 00:12:58
【问题描述】:

我有一个能够添加/删除项目行的表单。每当我想去编辑我的表单时,我都会运行一个异步调用来获取一些数据,然后相应地修补/设置表单控件的值。一切都按预期工作,但是,对于我的项目行,当我使用 Angular 2 的 patchValue 函数时,它只会用对象数组的第一个对象而不是所有对象修补表单组。

例如,如果我的表单有 3 行行项目,例如在发票中,则只会填充第一个行。谁能告诉我我做错了什么?

这是我的组件功能

constructor() {
    this.createCheckRequestForm();
}

createCheckRequestForm() {
    this.createRequestForm = this._fb.group({
      issued_date: [new Date().toISOString(), [<any>Validators.required]],
      due_date: [new Date().toISOString(), [<any>Validators.required]],
      invoice_number: ['', [<any>Validators.required]],
      how_to_send: ['Mail', [<any>Validators.required]],
      normal_processing: ['', []],
      is_corporation: ['', []],
      line_items: this._fb.array([this.initLineItem()])
    });
  }

  /**
   *  Init the line item for the form builder
   */
  initLineItem(options?) {
    return this._fb.group({
        description: ['', []],
        coding: ['', []],
        amount: ['', []],
        line_item_types: [[], []]
    });
  }


populateFormWithRequest(requestId) {
    this.formPopulationObs = this._checkRequests.getRequest(requestId).subscribe(requestData => {




      // Iterate through the line items and patch them
      let lineItems = [];
      requestData.line_items.forEach((lineItem, index) => {

        let lineItemTypes = [];
        if(lineItem.line_item_types) {
          lineItemTypes = lineItem.line_item_types;
        }

        // Separate key-store for the coding dropdown models
        this.lineItemCodings[index] = lineItem.coding;

        let lineItemObj = {
          description: lineItem.description,
          coding: lineItem.coding,
          amount: lineItem.amount,
          line_item_types: lineItemTypes,
        }
        lineItems.push(lineItemObj);
      })

      this.createRequestForm.patchValue({line_items: lineItems});
  })
}

如果我有这样的数组,“补丁”中只会显示第一个元素

[ 
 {amount: "600", coding: "-Kfxw732pfWUS5rU0TRu", description: "Cameras"},
 {amount: "600", coding: "-Kfxw732pfWUS5rU0TRu", description: "Lights"}
]

提前致谢!

【问题讨论】:

  • 看看这个:stackoverflow.com/questions/41645677/…。其中一些概念可能会对您有所帮助。
  • 根据@R.Richards 推荐的问题/答案,您必须遍历您的 FormArray 并单独修补每个项目
  • 嗯,在引用了该帖子中的示例后,我收到一个错误:“AbstractControl”类型上不存在“属性”。是什么赋予了? ://
  • 好的,所以我的错误消失了,但问题是我的代码似乎想要修补表单中尚不存在的line_items。默认情况下,表单只创建 1 个line_item,如果我尝试修补 3 个line_items,它只会获取第一个,因为我相信只有一个已被实例化。

标签: angular angular2-forms


【解决方案1】:

好的,所以为了让它工作,我实际上已经将表单组数组元素推送到已经存在的“line_items”控件上然后修补这些值。这是我的更新功能:

populateFormWithRequest(requestId) {
    this.formPopulationObs = this._checkRequests.getRequest(requestId).subscribe(requestData => {


      // Iterate through the line items and patch them
      requestData.line_items.forEach((lineItem, index) => {

        let lineItemTypes = [];
        if(lineItem.line_item_types) {
          lineItemTypes = lineItem.line_item_types;
        }

        // Create the item obj
        let lineItemObj = {
          description: lineItem.description,
          coding: lineItem.coding,
          amount: lineItem.amount,
          line_item_types: lineItemTypes,
        }

        const control = <FormArray>this.createRequestForm.controls['line_items'];
        control.push(this.initLineItem());
        control.at(index).patchValue(lineItemObj);
      });
  })
}

【讨论】:

    【解决方案2】:

    同样的结果,更简单一点 - 无需创建空项目并覆盖它:

    populateFormWithRequest(requestId) { 
      this.formPopulationObs = this._checkRequests.getRequest(requestId).subscribe(requestData => { 
        this.createRequestForm["line_items"] = 
    
    requestData.line_items.forEach(itm=>(<FormArray>this.createRequestForm["line_items"]).push(this.createRequestForm.group(itm)));
    
    )); 
    }); 
    }

    【讨论】:

      猜你喜欢
      • 2016-10-12
      • 2021-12-02
      • 2021-03-25
      • 1970-01-01
      • 2020-10-05
      • 2021-02-20
      • 2017-06-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多