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

Angular 7中mat-tab的ink bar偶尔无法显示的问题求助

Angular Material mat-tab Ink-Bar Not Displaying Correctly in Nested Tab Groups

I’ve run into this exact nested tab rendering quirk with Angular Material before—let’s break down what’s going on and fix it:

The Issue Breakdown

  • You’ve got a nested mat-tab-group setup: outer tabs for "Recent"/"Upcoming", inner tabs for match types (ALL/T20/ODI/TEST)
  • When switching between outer tabs, the inner tab’s ink-bar doesn’t appear initially
  • Toggling Dev Tools open/close makes the ink-bar pop up suddenly
  • After switching inner tabs and navigating back to the "Recent" outer tab, the inner tab resets to ALL (correct selectedIndex2 value) but the ink-bar stays hidden until Dev Tools is toggled

Root Cause

This is a classic rendering timing issue. Angular Material’s ink-bar calculates its position based on the actual DOM dimensions of the tab headers. When you switch outer tabs with animationDuration="0ms", you skip the framework’s internal rendering hooks that wait for DOM changes to settle. The ink-bar tries to compute its position before the inner tab-group’s DOM is fully sized or rendered—toggling Dev Tools triggers a reflow/repaint, which forces the ink-bar to recalculate correctly.

Fixes to Implement

1. Trigger Ink-Bar Update Manually (Most Reliable)

First, fix the duplicate template reference variable (#tabGroup is used twice—give each inner tab-group a unique name):

<mat-tab-group animationDuration="0ms" [selectedIndex]="activeIndex" (selectedTabChange)="onTabChange($event)" class="detail-page recent_tabs">
    <mat-tab label="Recent">
        <div class="card_left detail-page">
            <mat-tab-group #recentTabGroup [selectedIndex]="activeIndex2" (selectedTabChange)="onTabChange2($event)">
                <mat-tab label="ALL"></mat-tab>
                <mat-tab label="T20"></mat-tab>
                <mat-tab label="ODI"></mat-tab>
                <mat-tab label="TEST"></mat-tab>
            </mat-tab-group>
        </div>
    </mat-tab>
    <mat-tab label="Upcoming">
        <div class="card_left detail-page">
            <mat-tab-group #upcomingTabGroup [selectedIndex]="activeIndex2" (selectedTabChange)="onTabChange2($event)">
                <mat-tab label="ALL"></mat-tab>
                <mat-tab label="T20"></mat-tab>
                <mat-tab label="ODI"></mat-tab>
                <mat-tab label="TEST"></mat-tab>
            </mat-tab-group>
        </div>
    </mat-tab>
</mat-tab-group>

Then in your component, reference both tab groups and force the ink-bar to update when the outer tab changes:

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

@Component({
  // Your component metadata here
})
export class YourComponent {
  activeIndex = 0;
  activeIndex2 = 0;

  @ViewChild('recentTabGroup') recentTabGroup!: MatTabGroup;
  @ViewChild('upcomingTabGroup') upcomingTabGroup!: MatTabGroup;

  onTabChange(event: any) {
    this.activeIndex = event.index;
    // Push ink-bar update to the end of the event loop to ensure DOM is ready
    setTimeout(() => {
      this.getCurrentInnerTabGroup()?.updateInkBar();
    }, 0);
  }

  onTabChange2(event: any) {
    this.activeIndex2 = event.index;
  }

  private getCurrentInnerTabGroup(): MatTabGroup | undefined {
    return this.activeIndex === 0 ? this.recentTabGroup : this.upcomingTabGroup;
  }
}

2. Ditch animationDuration="0ms" (Quick Win)

Setting the animation duration to 0 skips critical rendering hooks that handle ink-bar positioning. Try changing it to animationDuration="10ms"—it’s visually instant but gives Angular Material enough time to process DOM changes properly.

3. Reinitialize Inner Tab Groups (Drastic but Effective)

If the above fixes don’t work, use *ngIf to ensure the inner tab-group is fully recreated when switching outer tabs:

<mat-tab label="Recent">
    <div class="card_left detail-page" *ngIf="activeIndex === 0">
        <mat-tab-group [selectedIndex]="activeIndex2" (selectedTabChange)="onTabChange2($event)">
            <mat-tab label="ALL"></mat-tab>
            <mat-tab label="T20"></mat-tab>
            <mat-tab label="ODI"></mat-tab>
            <mat-tab label="TEST"></mat-tab>
        </mat-tab-group>
    </div>
</mat-tab>
<mat-tab label="Upcoming">
    <div class="card_left detail-page" *ngIf="activeIndex === 1">
        <mat-tab-group [selectedIndex]="activeIndex2" (selectedTabChange)="onTabChange2($event)">
            <mat-tab label="ALL"></mat-tab>
            <mat-tab label="T20"></mat-tab>
            <mat-tab label="ODI"></mat-tab>
            <mat-tab label="TEST"></mat-tab>
        </mat-tab-group>
    </div>
</mat-tab>

Why This Works

The updateInkBar() method forces Angular Material to recalculate the ink-bar’s position based on the current DOM state. The setTimeout with 0ms delay pushes this calculation to the end of the event loop, ensuring the inner tab-group’s DOM is fully rendered before the ink-bar updates.

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 09:16:47