首页 文章

Angular2 Formbuilder - 引用FormArray元素

提问于
浏览
1

我们有一个表单,它接受服务响应,以便使用正确的字段名称填充表(我们的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数组对象,但仍会产生一个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,其中包含我正在比较服务响应的代码 . 从功能上讲,这是在完成预期的工作;但是,我'm still receiving an error: '错误TS2329:属性'controls'在类型'AbstractControl'上不存在 .

最终编辑以供将来参考:

类型化FormArray本身和FormGroup I 'm '发现'在删除初始打字稿错误方面是有效的 . 但是,在执行此操作时,我正在更新的表单控件开始抛出相同的"property 'control' on type '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

Key takeaways: typecasting FormGroups, FormArrays; referencing explicitly named controls with ['control'] format.

1 回答

  • 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);
        }
    }
    

    如果你记录它们,另一种方式应该有一堆“未定义”弹出 .

    这是一个展示这种微妙之处的掠夺者:http://plnkr.co/edit/JRbrPR2g2Kl3z6VJV5jQ?p=preview

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

    这是查找版本:

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

相关问题