#javascript #angular #typescript #angular-material #tabulator
#javascript #angular #typescript #angular-material #табулятор
Вопрос:
Новое в Tabulator.
У меня есть mat-tab-group, которую я использую для навигации по трем таблицам табуляторов.
Подход, который я использую, заключается в создании элемента div внутри component.ts и вставке его в существующий div в component.html .
Проблема, с которой я сталкиваюсь, заключается в том, что только на выбранной вкладке html загружен в DOM, поэтому любые элементы div на невыбранной вкладке отсутствуют в DOM, и на них нельзя ссылаться по идентификатору в моем component.ts. Когда я переключаюсь на вкладку, отличную от той, которая была загружена изначально, таблица табулятора не отображается.
Надеюсь, что у Angular есть перехват жизненного цикла, который вызывается для дочерних компонентов mat-tab, которые я могу использовать для запуска отрисовки, когда пользователь выбирает эту вкладку.
Конечно, я открыт для других / лучших подходов.
mat-tab-group html
<mat-tab-group *ngIf="hasData" mat-align-tabs="start">
<mat-tab *ngFor="let tablename of tableNames">
<ng-template matTabLabel>
<span>{{tablename}}</span>
</ng-template>
<div>
<app-tabulator-table *ngIf="dataServiceSelectedDate" [integrationName]="integrationName" [tableName]="tablename" [processDate]=dataServiceSelectedDate>
</app-tabulator-table>
</div>
</mat-tab>
</mat-tab-group>
tablulator-table.component.ts
export class TabulatorTableComponent implements OnInit {
@Input() tableName: string;
@Input() processDate: string;
@Input() integrationName: string;
fields: RunDataTableField[];
dataContent: RunDataContent;
tab = document.createElement("div");
tabColumns: any[] = [];
tabRows: any[] = [];
constructor(private clientDataService: ClientDataService) {
}
ngOnInit() {
this.clientDataService.getRunDataContent(this.integrationName, this.processDate, `${this.tableName}.json`).toPromise().then(dataContent =>
{
console.log(this.dataContent)
this.tabColumns = this.buildHeaders(dataContent);
this.tabRows = this.buildRows(dataContent);
this.redraw();
});
}
calculationFormatter = function (cell, formatterParams) {
var value = cell.getValue();
cell.getElement().style.backgroundColor = "#fdd0ff";
return value;
}
buildHeaders(runData: RunDataContent): any[] {
console.log(`${this.tableName}: creating headers object`);
var headers: any[] = [];
runData.schema.fields.forEach(f => {
var c: any = {};
c.title = f.name;
c.field = f.name;
c.headerFilter = "input"
switch (f.validationType) {
case "calculation": {
c.formatter = this.calculationFormatter
break;
}
case "raw": {
}
case "table": {
}
default: {
break;
}
}
if (f.tip != null amp;amp; f.tip.length > 0) {
c.tooltip = f.tip;
c.headerTooltip = f.tip;
}
headers = headers.concat(c);
});
console.log(`${this.tableName}: createad headers object`);
console.log(this.tabColumns);
return headers;
}
buildRows(runData: RunDataContent): any[] {
console.log(`${this.tableName}: creating rows object`);
var rows: any[] = [];
runData.rows.forEach(f => {
rows = this.tabRows.concat(f);
});
return rows;
}
private drawTable(): void {
new Tabulator(this.tab, {
layout: "fitDataStretch",
selectable: true,
selectableRangeMode: "click",
data: [],
columns: this.tabColumns,
height: "311px"
});
document.getElementById(`${this.tableName}`).appendChild(this.tab);
new Tabulator()
}
redraw() {
console.log(`${this.tableName}: drawing table`)
this.drawTable();
console.log(`${this.tableName}: completed drawing table`)
}
}
Комментарии:
1. Вы в конечном итоге нашли то, что искали здесь?
2. можете ли вы использовать
selectedTabChange
из mat-tab-group, чтобы прослушать изменение вкладки и повторно инициализировать таблицу tabulator (переместить ее за пределы вкладки — чтобы отобразить ее только один раз)
Ответ №1:
Согласно документам Angular Material, по умолчанию содержимое вкладки загружается с нетерпением. Загруженные вкладки инициализируют дочерние компоненты, но не вводят их в DOM, пока вкладка не будет активирована. Если вкладка содержит несколько сложных дочерних компонентов или содержимое вкладки зависит от вычислений DOM во время инициализации, рекомендуется отложить загрузку содержимого вкладки. Содержимое вкладки можно загружать лениво, объявляя тело в ng-шаблоне с атрибутом matTabContent .
Итак, правильным подходом было бы использовать ng-template с matTabContent . Пожалуйста, найдите ниже код для справки :
<mat-tab *ngFor="let table of tableNames" [label]="table">
<ng-template matTabContent>
<div>
<app-tabulator-table *ngIf="dataServiceSelectedDate"
[integrationName]="integrationName" [tableName]="tablename"
[processDate]=dataServiceSelectedDate>
</app-tabulator-table>
</div>
</ng-template>
</mat-tab>
Комментарии:
1. Протестировано и работает.