Angular2 Formbuilder - 引用FormArray元素

时间:2016-11-07 17:19:11

标签: angular angular2-forms formbuilder

我们有一个表单,它接受服务响应,以便使用正确的字段名称填充表(我们的FormArray)。给定正确的表单字段名称,我们尝试使用对另一个数据库的另一个服务调用来填充某些参数的字段。

一个简单的例子:

ngOnInit() {
  this.myForm = this._fb.group({
    name: [''],
    myArray: this._fb.array([])
  }),
  initArray();
}
private initArray(){
  this.arrayValsService.getValues.subscribe(
    response => {
                  for (item of response) {
                    let arrayItemGroup = this.createItemGroup(item.code, item.value);
                    const control = <FormArray>this.myForm.controls['myArray'];
                    control.push(arrayItemGroup);
                  }
                },
    err => {console.error(err);}
  };
}
private createItemGroup(code: string, value: string) {
  return this._fb_group({
    selected: [false],
    itemCode: [code],
    itemValue: [value],
    otherVal1: [''],    
    otherVal2: ['']  
  });
}

private setArray() {
  if(this.key !== undefined) {
    this.dataService.getData(this.key).subscribe(
      response => { 
        this.myForm.patchValue(response);
        for (let resItem of response.itemsSet) { 
          for (let formItem of <FormArray>this.myForm.controls['myArray']) {
            if (formItem.controls.itemCode === resItem.code) { // <== ISSUE HERE
              formItem.patchValue(response.itemsSet.resItem);
              formItem.controls.selected.setValue(true);
            }
          }
        }
      err => {console.error(err);}
    );
  }
}

我在控制台中收到错误,指出我们无法读取属性&#39;控件&#39;未定义的,&#39;发生在上面的标记线上。我需要引用数组中的各个表单控件组,以便相应地更新它们的值。我没有使用嵌套的for循环,而是尝试使用array.find来检查数组元素组中的特定控件:

const control = <FormArray>(this.myForm.controls['myArray'])
  .find(item => myArray.controls.item.itemCode === resItem.code)

这也行不通;遇到相同的问题,控件是未定义的属性。最重要的是,我需要一种方法来引用formArray的子​​元素和每个子元素的控件。

以下方法适用于迭代formArray.controls数组对象,但仍会产生一个typescript编译错误:

for (let resItem of response.itemsSet) {
  const control = this.myForm.controls['myArray'].controls
    .find((item:any) => item.value.itemCode === resItem.code);
  if(control) {control.controls.selected.setValue(true); // ...other value updates

control是一个数组对象,所以.find()在这里工作。在['myArray'].controls的子类型(FormGroup类型)中,有另一个数组对象child.value,其中包含我正在比较服务响应的代码。从功能上讲,这是在完成预期的工作;但是,我仍然收到错误:&#39;错误TS2329:属性&#39;控件&#39;类型&#39; AbstractControl&#39;。&#39;

上不存在

最终编辑以供将来参考:

对FormArray本身和FormGroup进行类型转换我发现&#39;有效地删除了最初的打字稿错误。但是,在执行此操作时,我正在更新的表单控件开始抛出相同的&#34;属性&#39;控件&#39;在类型&#39; AbstractControl&#39;&#34;错误。我根据this question更改了引用特定控件的格式。

最终结果:

for (let resItem of response.itemsSet) {
      const control = (<FormGroup>((<FormArray>(this.myForm.controls['myArray'])).controls
        .find((item:any) => item.value.itemCode === resItem.code)));
      if(control) {control.controls['selected']setValue(true); // ...other value updates

关键要点:类型化FormGroups,FormArrays;使用[&#39; control&#39;]格式引用显式命名的控件。

1 个答案:

答案 0 :(得分:1)

您拥有的formItem变量不是FormControl。然后,解决方案是直接访问FormArray上的controls数组并迭代:

for (let formItem of <FormArray>this.myForm.controls['myArray'].controls) {
    if ((<FormGroup>formItem).controls['itemCode'] === resItem.code) {
          <...>
          (<FormGroup>formItem).controls['selected'].setValue(true);
    }
}

另一种方式应该有一堆&#34; undefined&#34;如果你记录它们会弹出。

这里是一位展示这种微妙之处的傻瓜:http://plnkr.co/edit/JRbrPR2g2Kl3z6VJV5jQ?p=preview

对于你的TypeScript错误,如果你比编译器更清楚,那么你将不得不进行强制转换。

这里是查找版本:

(<FormGroup>control).controls['selected'].setValue(true);