javascript - 嵌套在 mat-tab 中的组件是否有生命周期挂钩?
问题描述
制表机新手。
我有一个 mat-tab-group 用于在三个 Tabulator 表中导航。
我使用的方法是在component.ts 中创建一个div 元素,并将其插入到component.html 中的现有div 中。
我遇到的问题是只有选定的选项卡将其 html 加载到 DOM 中,因此未选定选项卡中的任何 div 元素都不在 DOM 中,并且不能通过 id 引用到我的 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 && 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`)
}
}
解决方案
根据 Angular Material Docs,默认情况下,标签内容是急切加载的。急切加载的选项卡将初始化子组件,但在激活选项卡之前不会将它们注入 DOM。如果 tab 包含多个复杂的子组件或者 tab 的内容在初始化时依赖 DOM 计算,建议延迟加载 tab 的内容。通过在具有 matTabContent 属性的 ng-template 中声明正文,可以延迟加载选项卡内容。
因此,正确的方法是将 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>
推荐阅读
- python - 如何使一个类充当两个元素元组并解包元素?
- macos - 在网络上从 macOS 告诉 iPadOS
- python - Keras - 训练数据的预测准确性更差?
- json - WSO2 Enterprise Integrator 无法调用已部署的 API
- excel - 在 Excel 中创建“求解器”循环以运行最小化问题
- django - 如何在应用程序中使用反向 url 指向不同应用程序的模板?
- javascript - 如果最终用户没有回复,如何在一段时间后关闭 TextPrompt
- laravel-5 - 运行 php artisan config:cache 后,并非 .env 中的所有变量都被缓存
- node.js - 无法保存到 MongoDB 数据库并使用把手
- c# - 复杂的 Ef 核心映射/关系