Угловой материал - точно знать, какая вкладка была выбрана

Так что я мог пропустить что-то очевидное в документах, но я просто ищу простой способ найти вкладку, выбранную в следующем сценарии:

Посмотреть

<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 вернет 0, если я нажму первую вкладку, и 1, если я нажму третью вкладку, потому что вторая не отображается из-за *ngIf,

Это действительно имеет смысл для меня, однако из-за этого очень трудно узнать, какая вкладка была фактически нажата, в зависимости от того, какие из них были показаны для начала.

Я мог бы либо:

  • проверить снова для каждого состояния вкладки в onTabChange чтобы выяснить, какой индекс соответствует какой вкладке,
  • (вероятно) связать ViewChild(ren) ссылка на что-то и получить данные (например, data- атрибуты) через их родные элементы DOM.

Оба эти варианта кажутся слишком излишними.

Вопрос

В приведенном выше коде, какой будет правильный способ узнать, скажем, вкладку с надписью Label3 был нажат, без проверки на сам ярлык (что, очевидно, было бы ужасно)?

Простой Stackblitz, если это может помочь.

2 ответа

Решение

На самом деле отвечаю сам дважды, потому что я думаю, что это решение также интересно и, вероятно, ближе всего (пока) к тому, что я ищу:

Посмотреть

<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 приписывать.

Этот последний атрибут может поэтому использоваться для хранения "программного" имени вкладки (в отличие от ее открытого текста) и может быть легко получен на стороне сценария.

Использовать aria-labelledby атрибут для идентификации вкладки без использования удобочитаемых текстовых меток.

<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') { ... }
}

Не совсем то, что я искал, но вот лучшее решение, которое я нашел за это время:

Посмотреть

<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: спасибо @GreenMonkeyBoy на Gitter за помощь в поиске этого!

Другие вопросы по тегам