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
相关产品推荐
相关产品推荐

