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

Angular问题:最后一个mat-tab始终默认被选中

mat-tab-group添加禁用tab后默认选中禁用项的问题解决

我使用Angular Material的mat-tab-group组件,代码如下:

<mat-tab-group
  (selectedTabChange)="onTabSelect($event)"
  [disableRipple]="true"
  mat-align-tabs="start"
  animationDuration="0ms"
  [selectedIndex]="0"
  #tabs
>
  <mat-tab *ngFor="let setting of tabsAndFilters">
    <ng-template mat-tab-label>{{ setting['tabname'] }} </ng-template>
    <mat-tab-body>
      <dispo-einsatzuebersicht-einsatzuebersicht-aktuell
        [currentMonitorEinsatz]="currentMonitorEinsatz$ | async"
      ></dispo-einsatzuebersicht-einsatzuebersicht-aktuell>
    </mat-tab-body>
  </mat-tab>

  <mat-tab disabled>
    <ng-template mat-tab-label
      ><div [formGroup]="myGroup" class="ansicht-field-container">
        <sh-ui-forms-mat-select-control
          class="fng-input arbeitsplatz-field"
          formControlName="ansicht"
          [label]="'Ansicht'"
          [options]="currentNutzerParameter$ | async"
          [frozen]="form.disabled"
        ></sh-ui-forms-mat-select-control>
      </div>
    </ng-template>
  </mat-tab>
</mat-tab-group>

在末尾新增禁用状态的mat-tab后出现异常:页面加载时默认选中了这个禁用tab,尽管已设置selectedIndex="0";点击其他tab后无法再选中该禁用tab(此行为符合预期)。


问题原因

核心是异步数据加载导致的初始化渲染顺序冲突:

  • 如果tabsAndFilters是异步数据源(比如Observable),组件初始化时*ngFor还未渲染出正常tab,此时DOM中只有末尾的禁用tab,selectedIndex="0"会选中这个唯一存在的tab。
  • 当异步数据加载完成,*ngFor渲染出前面的正常tab后,mat-tab-group内部的选中状态不会自动同步更新,仍保持初始选中的禁用tab索引。

解决方案

方案1:延迟渲染禁用tab,确保正常tab优先加载

通过*ngIf控制禁用tab的渲染时机,等tabsAndFilters数据加载完成后再渲染,保证初始化时只有正常tab,selectedIndex="0"能正确选中第一个:

<mat-tab-group
  (selectedTabChange)="onTabSelect($event)"
  [disableRipple]="true"
  mat-align-tabs="start"
  animationDuration="0ms"
  [selectedIndex]="0"
  #tabs
>
  <mat-tab *ngFor="let setting of tabsAndFilters">
    <ng-template mat-tab-label>{{ setting['tabname'] }} </ng-template>
    <mat-tab-body>
      <dispo-einsatzuebersicht-einsatzuebersicht-aktuell
        [currentMonitorEinsatz]="currentMonitorEinsatz$ | async"
      ></dispo-einsatzuebersicht-einsatzuebersicht-aktuell>
    </mat-tab-body>
  </mat-tab>

  <!-- 仅当正常tab存在时渲染禁用tab -->
  <mat-tab disabled *ngIf="tabsAndFilters.length > 0">
    <ng-template mat-tab-label
      ><div [formGroup]="myGroup" class="ansicht-field-container">
        <sh-ui-forms-mat-select-control
          class="fng-input arbeitsplatz-field"
          formControlName="ansicht"
          [label]="'Ansicht'"
          [options]="currentNutzerParameter$ | async"
          [frozen]="form.disabled"
        ></sh-ui-forms-mat-select-control>
      </div>
    </ng-template>
  </mat-tab>
</mat-tab-group>

方案2:数据加载后手动重置选中索引

在组件类中订阅tabsAndFilters数据流,数据加载完成后手动设置mat-tab-group的选中索引:

import { ViewChild, OnInit } from '@angular/core';
import { MatTabGroup } from '@angular/material/tabs';

@Component({
  // 组件元数据
})
export class YourComponent implements OnInit {
  @ViewChild('tabs') tabs!: MatTabGroup;

  ngOnInit(): void {
    // 假设tabsAndFilters$是Observable类型的数据源
    this.tabsAndFilters$.subscribe(data => {
      if (data.length > 0) {
        // 用setTimeout确保DOM已更新
        setTimeout(() => {
          this.tabs.selectedIndex = 0;
        });
      }
    });
  }
}

方案3:绑定selectedIndex到动态变量

将selectedIndex绑定到组件类的变量,当tabsAndFilters数据变化时更新该变量:

export class YourComponent {
  selectedTabIndex = 0;

  constructor() {
    this.tabsAndFilters$.subscribe(data => {
      if (data.length > 0) {
        this.selectedTabIndex = 0;
      }
    });
  }
}

模板中修改绑定:

<mat-tab-group
  ...
  [selectedIndex]="selectedTabIndex"
  #tabs
>
<!-- 其余内容不变 -->
</mat-tab-group>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.12 23:32:08