Angular 8 и ошибка массива формы не может найти элемент управления с путем: индекс - PullRequest
0 голосов
/ 11 января 2020

Я отображаю массив форм внутри mat-table:

    <mat-table #table [dataSource]="dataSource" class="example-table"
        *ngIf="dataSource">
        <ng-container matColumnDef="invoice_id">
            <mat-header-cell *matHeaderCellDef>Invoice#</mat-header-cell>
            <mat-cell *matCellDef="let row">{{ row.invoice_id }}</mat-cell>
        </ng-container>

        <ng-container matColumnDef="update_status">

           <mat-header-cell *matHeaderCellDef>Update Status</mat-header-cell>

           <!-- <mat-cell *matCellDef="let row">{{ row.date_modified }}</mat-cell> -->

           <mat-cell *matCellDef="let row; let i = index;"
              formArrayName="status_array">
              <div [formGroupName]="i">
            <mat-form-field>
                <mat-label>Status</mat-label>
                <mat-select id="receipt_status"
                    formControlName="receipt_status" placeholder="Status">
                    <mat-option (click)="onChange(row, i, 'ms', status.id)"
                        *ngFor="let status of ReceiptStatus;"
                        [value]="status.id">
                        {{status.name}}
                    </mat-option>
                </mat-select>
            </mat-form-field>&nbsp;
        </div>
    </mat-cell>

</ng-container>

<mat-header-row *matHeaderRowDef="displayedColumns"></mat-header-row>
            <mat-row *matRowDef="let row; columns: displayedColumns;"></mat-row>
</mat-table>

<mat-paginator #paginator [length]="length" [pageSize]="pageSize"
        [showFirstLastButtons]="true" [hidePageSize]="true"
        (page)="loadData($event)" *ngIf="dataSource && length > 0">
    </mat-paginator>
</div>

В сценарии .ts:

внутри ngOnInit:

ngOnInit {

this.createStatusArray();

}

createStatusArray(){
    this.statusArrayForm = this.fb.group({
      'status_array': this.createArray()
    })

  }

  createArray(): FormArray {
    return new FormArray(this.dataSource.data.map(item => new FormGroup({
      receipt_status: new FormControl(item['is_active']),
    })));

  }

Источник данных устанавливается из вызова API:

if(response && response.status == "success"){
        this.receiptMsg = false;

        this.receiptsArray = response.response;
        this.length = this.receiptsArray.length;
        this.dataSource = response.response;
        // console.log(this.dataSource)
          setTimeout(() => {
            this.dataSource.paginator = this.paginator;
          }, 50);

Статусы, добавленные в *ngFor:

ReceiptStatus = [
    {id: 0, name: 'Inactive'},
    {id: 1, name: 'Active'}
  ];

Я продолжал получать следующие ошибки:

ОШИБКА Ошибка: не удается найти элемент управления с путем: 'status_array -> 1'

1 Ответ

1 голос
/ 12 января 2020

Вам нужно создать formArray, когда вы получаете данные, а не в ngOnInit, тем более лучше, чтобы источником данных таблицы матов был formArray

  if(response && response.status == "success"){
        this.receiptMsg = false;
        this.receiptsArray = response.response;
        this.length = this.receiptsArray.length;
        this.dataAuxiliar=response.response; //<--use an array to store the data
        this.formArray = this.createArray(response.response);
          setTimeout(() => {
            this.dataSource.paginator = this.paginator;
          }); //is innecesary give a "time", If we make a setTimeout, angular 
              //make the instruction in a "second-round"

  //to createArray pass the data
   createArray(data:any[]): FormArray {
    return new FormArray(data.map(item => new FormGroup({
      receipt_status: new FormControl(item['is_active']),
    })));

После того, как вы можете сделать

  <!--see that the dataSource is formArray.controls-->
  <!--it's not necesary that the formArray "belong" to a formGroup-->
  <!--if belong to a formGroup be sure that you has a getter like

     get formArray(){
       return this.form?this.form.get('myFormArray') as FormArray:null
     }
  -->
  <mat-table #table *ngIf="formArray" 
        [dataSource]="formArray.controls" class="example-table">
        <--for an element of dataAuxiliar use let i=index and
            dataAuxiliar[i].propertieOfThe data, e.g. -->
        <ng-container matColumnDef="invoice_id">
            <mat-header-cell *matHeaderCellDef>Invoice#</mat-header-cell>
            <mat-cell *matCellDef="let row;let i=index">{{ dataAuxiliar[i].invoice_id }}</mat-cell>
        </ng-container>

       <--for a control of the FormArray use 
              [formControl]=element.get('field of the formGroup')-->
        <ng-container matColumnDef="update_status">
           <th mat-header-cell *matHeaderCellDef> Status</th>
           <td mat-cell *matCellDef="let element">
               <input [formControl]="element.get('receipt_status')">
           </td>
         </ng-container>

Пример formArray в mat-таблице можно найти в этом ТАК вопрос

...