[解決]Reactive Form在AOT編譯時報錯:Argument of type ‘AbstractControl’ is not assignable to parameter of type ‘FormGroup’

需求: 我要把一組一組的FormGroup塞入FormArray中,編譯時都沒有問題,但在進行AOT編譯的時候卻出現了以下的錯誤訊息:

Argument of type ‘AbstractControl’ is not assignable to parameter
of type ‘FormGroup’

附上原始碼:
↓↓↓ .ts檔

ngOnInit() {
    const passArray = new FormArray([]);
    const passCondition = this.editService.getPassConditionArray();
    for (const condition of passCondition) {
      console.log(condition);
      passArray.push(
        new FormGroup({
          condition: new FormGroup({
            diveAttribute: new FormControl(condition.condition['diveAttribute']),
            operator: new FormControl(condition.condition['operator']),
            value: new FormControl(condition.condition['value'])
          }),
          logical: new FormControl(condition['logical'])
        })
      );
    }

  getConditionArrayForm(form: FormGroup) {
    return form.controls; //直接在template寫.controls會報錯,所以迂迴的寫了這一段
  }

↓↓↓ .html檔

<form [formGroup]="passForm">
<div formArrayName="passArray">
  <div [formGroupName]="i" *ngFor="let condition of getConditionArrayForm(passForm.get('passArray'));let i = index">
    //***報錯在上面那行***
    <div *ngIf="i !== 0">
      <div class="col-2">
        <select formControlName="logical" class="form-control" >
          <option value="and">且</option>
          <option value="or">或</option>
        </select>
      </div>
    </div>
    <div class="form-row" formGroupName="condition">
      <div class="col-5">
          <select formControlName="diveAttribute" class="form-control">
              <option *ngFor="let item of diveItems;" [value]="item.dataValue">
                {{item.viewValue}}
              </option>
            </select>
      </div>
      <div class="col-2">
        <select formControlName="operator" class="form-control">
          <option *ngFor="let operator of operators" [value]="operator">
            {{ operator }}
          </option>
        </select>
      </div>
      <div class="col-4">
        <input type="text" formControlName="value" class="form-control" placeholder="請輸入數值">
      </div>
    </div>
  </div>
</div>
</form>

你可以把問題放在 stackblitz 嗎? 我無法重現你的問題

感謝!目前已經解決了,問題是出在 *ngFor那行,以下分享一下我踩雷的過程:

以下是我表單的結構

this.conditionForm = new FormGroup({
      name: new FormControl(),
      conditions: new FormArray([
        new FormGroup({
          condition: new FormGroup({
            diveAttribute: new FormControl(),
            operator: new FormControl(),
            value: new FormControl(),
          }),
          logical: new FormControl()
        })
      ]),
      content: new FormControl()
    });

而最初我在Template取得FormArray內容的方式如下所示:
*ngFor="let condition of conditionForm.controls.conditions.controls"

但這個寫法會不給過,錯誤訊息如下:

AbstractControl沒有屬性’controls’

原本我的解法是在Template透過呼叫函式的方式讓這個FormArray硬綁上controls並取得內容,作法如下:

ts檔:

  getConditionArrayForm(form: FormGroup) {
    return form.controls; 
  }

html檔:
*ngFor="let condition of getConditionArrayForm(conditionForm.get('conditions'))"

但這個解法到後來要進行AOT編譯時卻又報錯了,狀況如本文所述 :cold_sweat:

經過一番研究後,發現其實只要對一開始的conditionForm.controls.conditions做強制轉型就可以順利綁上controls,作法如下:

ts檔:

conditionArray: AbstractControl[];
ngOnInit() {
    this.conditionArray = (<FormArray>this.conditionForm.controls.conditions).controls;
    //強制轉型成FormArray
  }

html檔:
*ngFor="let condition of conditionArray"

Works!
:grinning:

1個讚