2016-11-07 99 views
1

我们有一个表单需要一个服务响应,以便用正确的字段名填充一个表(我们的FormArray)。鉴于正确的表单字段名称,我们试图通过对另一个数据库的另一个服务调用来填充某些参数的字段。Angular2 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);} 
    ); 
    } 
} 

我在我们“不能读取属性‘控制台接收到错误控制’的未定义的,”以上发生在标记行。我需要引用数组中的各个表单控件组,以便相应地更新它们的值。代替使用嵌套for循环的,我还试图用array.find以便检查该阵列元件组中的特定控制:

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

这也不工作;遇到与作为未定义属性的控件相同的问题。底线是,我需要一种方法来引用formArray的子​​元素和每个这些子元素的控件。

以下方法适用于通过formArray.controls阵列对象迭代,但仍产生了打字稿编译错误:

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,它具有我正在比较服务响应的代码。在功能上,这是做预期的工作;但是,我仍然收到一个错误:'错误TS2329:属性'控件'不存在于'AbstractControl'类型'。'

以供将来参考决赛编辑:

类型转换的FormArray本身和我“发现”的FormGroup是有效地去除初始打字稿错误。然而,在这样做的时候,我正在更新的窗体控件开始在类型为'AbstractControl'的错误上抛出相同的“属性”控件。我根据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;使用['control']格式引用明确命名的控件。

回答

1

您所拥有的formItem变量不是FormControl。该解决方案的话,是可以直接访问的FormArray控件数组并重复:

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

其他方式应该有一堆“未定义”弹出,如果你登录他们。

这里有一个plunker展示这种细微之处:http://plnkr.co/edit/JRbrPR2g2Kl3z6VJV5jQ?p=preview

为了您的打字稿的错误,如果你知道比编译器那么你将不得不投好。

这对于查找版本:

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

按照这种模式使我一对夫妇的TS错误:类型“FormArray”是不是数组或字符串;属性'controls'在类型'AbstractControl'上不存在。在你的plnkr中,你没有将'['myArray'] .'作为''(我相信它是数组类型)。我删除了该投射,但仍然收到类型为AbstractControl的错误,并且该方法不会产生预期的结果。我将用一种功能足够的方法编辑问题,但仍会产生相同的错误。 –

+0

你有没有试过铸造?如果你比编译器更了解,你将不得不告诉它。更新了答案以提供示例。 – silentsod