You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为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>

注意:这种方式会频繁创建销毁组件,性能不如方案一,仅适合简单场景。


关键注意点

  1. 不要依赖 ngOnInit() 处理动态变化的输入数据,它只执行一次
  2. 更新 MatTableDataSource 时,优先使用 dataSource.data = 新数组,而非重新实例化对象
  3. 如果父组件维护 incomeArray 等数据源,要确保 company 变化时同步更新这些数组

内容的提问来源于stack exchange,提问作者jameseg

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 00:15:00