Angular FormArray patchValue错误:TypeError:value.forEach不是函数 - 如何解决?

Angular FormArray patchValue错误:TypeError:value.forEach不是函数 - 如何解决?

问题描述:

Page最初是作为模板驱动的形式编写的,但正在转换为反应式以添加自动保存功能。Angular FormArray patchValue错误:TypeError:value.forEach不是函数 - 如何解决?

在页面组件的构造我定义反应形式变量:

this.form = fb.group({ 
    reviewer: '', 
    position: '', 
    officeName: '', 
    rows: fb.array([]), 
    comments1: '', 
    comments2: '', 
    comments3: '' 
}); 

“行”是与这一问题有关的领域。

在ngInit中,通过web api发出请求以检索持久化表单数据。数据以行数组的形式检索,每个数组包含6个单元格的数组。第三个单元格将绑定到FormControl,其他单元格将被渲染为静态文本。

this.rows = summaryReportQuestion.map(summaryReportQuestionObj => { 
    return { 
     cells: [ 
      summaryReportQuestionObj.questionID, 
      summaryReportQuestionObj.question, 
      (summaryReportQuestionObj.columnSign == '$' ? (summaryReportQuestionObj.columnSign + ' ' + summaryReportQuestionObj.target) : summaryReportQuestionObj.target + ' ' + summaryReportQuestionObj.columnSign), 
      (summaryReportQuestionObj.budget == null ? summaryReportQuestionObj.budget : (summaryReportQuestionObj.columnSign == '$' ? summaryReportQuestionObj.columnSign + ' ' + this.utilityService.formatNumberWithCommas(Math.floor(summaryReportQuestionObj.budget), false) : summaryReportQuestionObj.budget + ' ' + summaryReportQuestionObj.columnSign)), 
      (summaryReportQuestionObj.average == null ? summaryReportQuestionObj.average : (summaryReportQuestionObj.columnSign == '$' ? summaryReportQuestionObj.columnSign + ' ' + this.utilityService.formatNumberWithCommas(Math.floor(summaryReportQuestionObj.average), false) : summaryReportQuestionObj.average + ' ' + summaryReportQuestionObj.columnSign)), 
      (summaryReportQuestionObj.top20Percent == null ? summaryReportQuestionObj.top20Percent : (summaryReportQuestionObj.columnSign == '$' ? summaryReportQuestionObj.columnSign + ' ' + this.utilityService.formatNumberWithCommas(Math.floor(summaryReportQuestionObj.top20Percent), false) : summaryReportQuestionObj.top20Percent + ' ' + summaryReportQuestionObj.columnSign)) 
     ] 
    }; 
}); 

let faRows = new FormArray([]); 
for (var i = 0, len = this.rows.length; i < len; i++) { 
    let row = this.rows[i].cells; 
    for (var j = 0, length = this.rows[i].cells.length; j < length; j++) { 
     let fc = new FormControl(this.rows[i].cells[j]); 
     faRows.push(fc); 
    } 
} 

// this.form.setValue({rows: faRows}); 
// this.form.setControl('rows', faRows); 

在HTML:

<tbody> 
    <tr *ngFor="let row of rows;let r = index" [attr.data-index]="r"> 
     <ng-container> 
      <td *ngFor="let cell of row.cells;let i = index" [attr.data-index]="i"> 
       <span *ngIf="i != 2">{{cell}}</span> 
       <!-- <input type="text" formControlName="form.rows[r]" *ngIf="i == 2"> --> 
      </td> 
     </ng-container> 
    </tr> 
</tbody> 

基于一个评论,我已经澄清了我的意图和代码的答案。 [感谢你@amal和@DeborahK] 我现在只搭售数据的一个单元从每一行到一个FormControl,每行中的其他细胞显示: {{细胞}}

因此,我需要渲染this.rows的内容(如html所示)以及this.form.rows。

我目前有两个问题,理解如何做到这一点。在打字稿中,留下循环的最后一块循环遍历创建行'FormControls的数据行,数组faRows恰恰包含我期望的内容,一个FormControl的FormArray,并且每个都检索到它的正确关联保存值。但是当试图从this.rows复制数据来为form.rows创建FormControls时,我无法让setValue或setControl正常工作。这可能与html页面上FormControl的命名有关,这是我的第二个问题。

我不清楚如何引用表单变量来动态地在html中创建formControlName。这是我想象的,但它不起作用。

<input type="text" formControlName="form.rows[r]" *ngIf="i == 2"> 

Page rendered as template driven form

+0

只看代码,我有一种感觉,你的初始化formArray的分配是不正确的。您是否期望对1个单元格内的每个元素都有formArray控件?像questionId,问题,columnSign,预算等。? – amal

+0

@amal:我修改了原始代码,因为我不打算对1行内的每个元素都有formArray控件。相反,只有一个元素(第三个,实际)会有一个关联的FormControl。你能解释一下我如何混合这两个阵列,一个是反应性的阵列吗? – lynnjwalker

+0

不清楚你想做什么以及你做错了什么。如果你想引用一个被动的formArray控件到模板,你还需要引用并使用[formArrayName](https://angular.io/api/forms/FormArrayName)。你可以创建一个复制品或展示你最终希望这个页面看起来像什么样(你想达到什么目的)? – amal

据我所知,这是不可能调用.patchValue与FormArray。

我的表单设置类似,其中标签是我的FormArray。

this.productForm = this.fb.group({ 
     productName: ['', [Validators.required, 
          Validators.minLength(3), 
          Validators.maxLength(50)]], 
     productCode: ['', Validators.required], 
     starRating: ['', NumberValidators.range(1, 5)], 
     tags: this.fb.array([]), 
     description: '' 
    }); 

当编辑设定数据,我不得不这样做:

this.productForm.patchValue({ 
     productName: this.product.productName, 
     productCode: this.product.productCode, 
     starRating: this.product.starRating, 
     description: this.product.description 
    }); 
    this.productForm.setControl('tags', this.fb.array(this.product.tags || [])); 

我用patchValue每个简单FormControls和使用setControl的FormArray。

你可以尝试一下,看看是否能解决你的问题。