Я пытаюсь создать компонент таблицы, в который пользователь может добавить конечную точку REST для загрузки в данные.Предполагается, что данные будут массивом произвольных объектов, поэтому здесь не обязательно возможна строгая схема.
Проблема в том, что я не могу получить таблицу и ее paginator, чтобы ждать рендеринга до тех пор, пока я не сделаю запросна конечной точке REST.У меня есть версия, которая работает с разбивкой по страницам, но перед загрузкой данных по-прежнему появляются страницы (и пустая таблица).
Я пытался использовать AfterViewChecked, а также различные места инициализации paginator иТаблица.
Образец Stackblitz здесь. Обратите внимание, что вам не нужно вводить действительную конечную точку в модальном режиме, так как она выбирается из фиктивной.Я оставил модальное состояние как можно ближе к состоянию по умолчанию.
Файл component.ts:
import { Component, OnInit, ViewChild } from '@angular/core';
import { MatPaginator, MatTable, MatTableDataSource } from '@angular/material';
import { DomSanitizer } from '@angular/platform-browser';
import { RestService } from '../rest.service';
@Component({
providers: [RestService],
selector: 'table-widget',
styleUrls: ['./table-widget.component.scss'],
templateUrl: './table-widget.component.html',
})
export class TableWidgetComponent implements OnInit {
public dataSource: MatTableDataSource<any> = new MatTableDataSource();
// map of header names (which are keys in series) to whether they should be visible
public headers: Map<string, boolean>;
public headerKeys: string[];
@ViewChild(MatTable) private table: MatTable<any>;
@ViewChild(MatPaginator) private paginator: MatPaginator;
// array of header titles, to get arround ExpressionChangedAfterItHasBeenCheckedError
private restEndpoint: string;
private editModalVisibility: boolean;
constructor(private restService: RestService, private sanitizer: DomSanitizer) { }
// called each time an AppComponent is initialized
public ngOnInit(): void {
this.headers = new Map<string, boolean>();
this.editModalVisibility = false;
this.dataSource.paginator = this.paginator;
}
public eventFromChild(data: string): void {
this.restEndpoint = data;
// return value of rest call
this.restService.getFromEndpoint(this.restEndpoint)
.subscribe((series) => {
this.dataSource.data = series;
this.table.renderRows();
// set keys, unless series is empty
if (series.length > 0) {
Object.keys(this.dataSource.data[0]).forEach((value) => {
this.headers.set(value, true);
});
}
this.headerKeys = Array.from(this.headers.keys());
});
}
.
.
.
}
и файл HTML:
<div [ngClass]="['table-widget-container', 'basic-container']">
<div [ngClass]="['table-container']">
<mat-table [ngClass]="['mat-elevation-z8']" [dataSource]="dataSource">
<ng-container *ngFor="let header of getVisibleHeaders()" matColumnDef={{header}}>
<mat-header-cell *matHeaderCellDef> {{header | titlecase}} </mat-header-cell>
<mat-cell *matCellDef="let entry"> {{entry[header]}} </mat-cell>
</ng-container>
<mat-header-row *matHeaderRowDef="getVisibleHeaders()"></mat-header-row>
<mat-row *matRowDef="let row; columns: getVisibleHeaders();"></mat-row>
</mat-table>
<mat-paginator #paginator [pageSize]="5" [pageSizeOptions]="[5, 11, 20]"></mat-paginator>
</div>
<button *ngIf="dataSource.data.length" (click)="openModal()" class="add-rest-button">
Edit Table
</button>
<add-rest-button (sendDataToParent)="eventFromChild($event)"></add-rest-button>
</div>
КогдаЯ пытаюсь добавить *ngIf="dataSource.data.length"
к mat-table
и mat-paginator
, либо отображается страница, но не «привязана» к таблице, либо таблица отображается без данных, и я получаю следующую ошибку:
TypeError: Cannot read property 'renderRows' of undefined
Я понимаю, что эта ошибка возникает из-за того, что таблица не определена из-за директивы ngIf, но я не уверен, как иначе эффективно скрыть таблицу.