Angular Material - 确切知道选择了哪个选项卡

Angular Material - Know exactly which tab was selected

所以我可能错过了文档中明显的内容,但我只是在寻找一种简单的方法来查找在以下情况下选择了哪个选项卡:

查看

<mat-tab-group (selectedTabChange)="onTabChange($event)">
  <mat-tab *ngIf="true" label="Label1">Content 1</mat-tab>
  <mat-tab *ngIf="false" label="Label2">Content 2</mat-tab>
  <mat-tab *ngIf="true" label="Label3">Content 3</mat-tab>
</mat-tab-group>

显然,在我的实际代码中条件是动态的。这只是示例。

脚本

onTabChange(event: MatTabChangeEvent) {
  // ?
}

问题

在上面的脚本中,如果单击第一个选项卡,event.index 将 return 0,如果单击第三个选项卡 ,则 1,因为由于 *ngIf,第二个未显示。

这对我来说确实有意义,但是很难知道实际点击了哪个选项卡,具体取决于开始显示的选项卡。

我可以:

  • 再次测试 onTabChange 中的每个选项卡条件,以确定哪个索引对应于哪个选项卡,
  • (可能)将 ViewChild(ren) 引用绑定到某物并通过其原生 DOM 元素检索数据(例如 data- 属性)。

虽然这两个选项看起来都超级矫枉过正。

问题

在上面的代码中,如果不对标签本身进行测试(这显然是可怕的),知道点击标签 Label3 的正确方法是什么?

Simple Stackblitz 如果可以的话。

不完全是我想要的,但这是我在此期间找到的最佳解决方案:

查看

<mat-tab-group (selectedTabChange)="onTabChange($event)">
  <mat-tab *ngIf="true" data-name="tab1" label="Label1">Content 1</mat-tab>
  <mat-tab *ngIf="false" data-name="tab2" label="Label2">Content 2</mat-tab>
  <mat-tab *ngIf="true" data-name="tab3" label="Label3">Content 3</mat-tab>
</mat-tab-group>

脚本

onTabChange(event: MatTabChangeEvent) {
  const tabName = event.tab.content.viewContainerRef.element.nativeElement.dataset.name;
  // ...
}

看起来有点老套(而且非常冗长),但确实有用。

PS:感谢 Gitter 上的@GreenMonkeyBoy 帮助找到这个!

实际上我自己回答了两次,因为我认为这个解决方案也很有趣,并且可能(目前)最接近我正在寻找的东西:

查看

<mat-tab-group (selectedTabChange)="onTabChange($event)">
  <mat-tab *ngIf="true" label="tab1">
    <ng-template mat-tab-label>Label 1</ng-template>
    Content 1
  </mat-tab>
  <mat-tab *ngIf="false" label="tab2">
    <ng-template mat-tab-label>Label 2</ng-template>
    Content 2
  </mat-tab>
  <mat-tab *ngIf="true" label="tab3">
    <ng-template mat-tab-label>Label 3</ng-template>
    Content 3
  </mat-tab>
</mat-tab-group>

脚本

onTabChange(event: MatTabChangeEvent) {
  const tabName = event.tab.textLabel;
  // ...
}

基本上,这使用另一种方式向选项卡添加(标题)文本标签,使用 <ng-template>,这似乎优先于 label 属性。

因此,后一个属性可用于存储选项卡的 "programmatic" 名称(与其 public 文本相对),并且可以在脚本端轻松检索。

使用 aria-labelledby 属性来识别选项卡,而无需求助于 human-readable 文本标签。

<mat-tab aria-labelledby="tab-x">
    <span *matTabLabel id="tab-x" i18n>Tab X</span>
</mat-tab>

代码中:

onTabChange(event: MatTabChangeEvent) {
    const tabId = event.tab.ariaLabelledby;
    if (tabId === 'tab-x') { ... }
}