2017-09-29 42 views
1

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

回答

6

據我所知,這是不可能調用.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。

你可以嘗試一下,看看是否能解決你的問題。

相關問題