如何为Angular中每个mat-tab加载不同的dataSource?
问题分析与解决方案
你的核心问题在于:mat-tab 默认会缓存已加载的标签页内容,子组件的 ngOnInit() 仅在首次初始化时执行一次;同时子组件没有监听输入属性的变化,导致切换标签时无法更新数据。以下是具体的修复方案:
方案一:让子组件监听输入变化(推荐)
修改 app-table 子组件,通过 ngOnChanges 或 @Input setter 监听 company 或数据类型的变化,动态生成表格数据源:
子组件代码(app-table.component.ts)
import { Component, Input, OnChanges, SimpleChanges } from '@angular/core'; import { MatTableDataSource } from '@angular/material/table'; @Component({ selector: 'app-table', templateUrl: './table.component.html', styleUrls: ['./table.component.css'] }) export class TableComponent implements OnChanges { @Input() company: any; @Input() tableType: 'income' | 'balance' | 'cash'; dataSource = new MatTableDataSource<any>([]); // 监听输入属性变化,重新解析数据 ngOnChanges(changes: SimpleChanges): void { if ((changes['company'] && !changes['company'].firstChange) || changes['tableType']) { this.refreshDataSource(); } } // 初始化时也执行一次解析 ngOnInit(): void { this.refreshDataSource(); } private refreshDataSource(): void { if (!this.company || !this.tableType) return; // 根据类型解析对应数据 switch(this.tableType) { case 'income': this.dataSource.data = this.company.incomeData || []; break; case 'balance': this.dataSource.data = this.company.balanceData || []; break; case 'cash': this.dataSource.data = this.company.cashData || []; break; } } }
父组件模板修改
<mat-tab-group> <mat-tab label="INCOME"> <app-table *ngIf="company" [company]="company" [tableType]="'income'"></app-table> </mat-tab> <mat-tab label="BALANCE"> <app-table *ngIf="company" [company]="company" [tableType]="'balance'"></app-table> </mat-tab> <mat-tab label="CASH"> <app-table *ngIf="company" [company]="company" [tableType]="'cash'"></app-table> </mat-tab> </mat-tab-group>
方案二:强制销毁隐藏的标签页组件
如果不想修改子组件逻辑,可以给 mat-tab 添加 destroyOnHide 属性,切换标签时销毁重建子组件,让 ngOnInit() 重新执行:
<mat-tab-group> <mat-tab label="INCOME" [destroyOnHide]="true"> <app-table *ngIf="company" [company]="company" [dataSource]="incomeArray"></app-table> </mat-tab> <mat-tab label="BALANCE" [destroyOnHide]="true"> <app-table *ngIf="company" [company]="company" [dataSource]="balanceArray"></app-table> </mat-tab> <mat-tab label="CASH" [destroyOnHide]="true"> <app-table *ngIf="company" [company]="company"></app-table> </mat-tab> </mat-tab-group>
注意:这种方式会频繁创建销毁组件,性能不如方案一,仅适合简单场景。
关键注意点
- 不要依赖
ngOnInit()处理动态变化的输入数据,它只执行一次 - 更新
MatTableDataSource时,优先使用dataSource.data = 新数组,而非重新实例化对象 - 如果父组件维护
incomeArray等数据源,要确保company变化时同步更新这些数组
内容的提问来源于stack exchange,提问作者jameseg
相关产品推荐
相关产品推荐

