Angular2 Formbuilder - 引用 FormArray 元素

Angular2 Formbuilder - Referencing FormArray Element

我们有一个接受服务响应的表单,以便用正确的字段名称填充 table(我们的 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);}
    );
  }
}

我在控制台中收到一条错误消息,提示我们“无法读取未定义的 属性 'controls'”,出现在上面标记的行中。我需要引用数组中的各个表单控件组,以便相应地更新它们的值。我没有使用嵌套的 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:属性 'controls' 在类型 'AbstractControl' 上不存在。”

供将来参考的最终编辑:

对 FormArray 本身和我是 'finding' 的 FormGroup 进行类型转换有效地消除了最初的打字稿错误。然而,在这样做时,我正在更新的表单控件开始抛出相同的 "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

要点:类型转换 FormGroups、FormArrays;使用 ['control'] 格式引用明确命名的控件。

您拥有的 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);
    }
}

另一种方式应该有一堆 "undefined" 如果你记录它们弹出。

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

对于您的 TypeScript 错误,如果您比编译器更了解,那么您将不得不进行转换。

这是查找版本:

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