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

lyn*_*ker 3 reactive-forms angular formarray

页面最初是作为模板驱动的表单编写的,但正在转换为被动,以便添加自动保存功能.

在页面组件的构造函数中,我定义了响应式表单变量:

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

'rows'是与此问题相关的字段.

在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);
Run Code Online (Sandbox Code Playgroud)

在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>
Run Code Online (Sandbox Code Playgroud)

基于评论和答案,我已经澄清了我的意图和代码.[谢谢@amal和@DeborahK]我现在只将每行数据的一个单元格绑定到FormControl,每行中的其他单元格显示为:{{cell}}

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

我目前有两个问题,了解如何实现这一目标.在typescript中,让最后一个循环块迭代在创建行'FormControls'的数据行上,数组faRows正好包含我所期望的FormControls FormArray,并且每个都检索到它正确的相关保存值.但是当试图从this.rows复制数据以创建form.rows的FormControls时,我无法使setValue或setControl正常工作.这可能与html页面上FormControl的命名有关,这是我的第二个问题.

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

 <input type="text" formControlName="form.rows[r]" *ngIf="i == 2">
Run Code Online (Sandbox Code Playgroud)

页面呈现为模板驱动的表单

Deb*_*ahK 23

据我所知,无法使用FormArray调用.patchValue.

我的表单设置类似,其中tags是我的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: ''
    });
Run Code Online (Sandbox Code Playgroud)

设置编辑数据时,我必须这样做:

    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 || []));
Run Code Online (Sandbox Code Playgroud)

我用于patchValue每个简单的FormControls并用于setControlFormArray.

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

  • 仅供参考-`patchValue`确实可以在`FormArray`上使用,但是不会调整数组的大小,因此仅当您设置的数据长度与`FormArray'相同时才可以使用。(对于这个问题并没有真正的帮助,但是需要注意) (4认同)