Связка Mat-tab-group [(selectedIndex)] = ... является ненадежной - PullRequest
0 голосов
/ 31 января 2020

Я использую Angular и модуль MaterialTabs.

У меня есть список вкладок в моем компоненте, который я отображаю с помощью mat-tabs и ngFor, плюс еще одна отключенная вкладка с кнопкой плюс. При нажатии кнопки «плюс» я хотел бы добавить новую вкладку и сразу же сфокусироваться на этой вкладке. (Аналогично тому, как работают вкладки браузера.)

Вот как это выглядит:

Example

Я делаю это в двух направлениях привязка свойства к свойству selectedIndex группы mat-tab-group и установка его из моего компонента в обработчике события нажатия кнопки.

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

Однако я столкнулся с проблемой, когда если я заново загружаю страницу и сначала нажимаю на кнопку, привязка свойства как-то нарушается:

Issue

Один щелчок по любой из вкладок, похоже, навсегда устраняет проблему. Проблема возвращается, когда вы перезагружаете страницу.

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

[(selectedIndex)]="selectedIndexBinding"

Так как selectedIndex может быть равен 1, а selectedIndexBinding равен 0?

Как я могу решить эту проблему?

Пример в реальном времени:

https://stackblitz.com/edit/angular-82vgrj

Код:

src / app / app.component. html

<mat-tab-group [(selectedIndex)]="selectedIndexBinding" #tabGroup>
  <mat-tab *ngFor="let tab of tabs">
    <ng-template mat-tab-label>
      {{ tab }}
    </ng-template>
  </mat-tab>
  <mat-tab disabled>
      <ng-template mat-tab-label>
        <button mat-icon-button (click)="addTab()">
          +
        </button>
      </ng-template>
  </mat-tab>
</mat-tab-group>

selectedIndex: {{ tabGroup.selectedIndex }}<br />
selectedIndexBinding: {{ selectedIndexBinding }}

src / app / app.component.ts

import { Component } from '@angular/core';

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {
  public selectedIndexBinding = 0;
  public tabs = [];

  public addTab() {
    this.tabs.push("Tab");
    this.selectedIndexBinding = this.tabs.length - 1;
  }
}

1 Ответ

1 голос
/ 31 января 2020

Ваша проблема связана с тем, как вы устанавливаете новый индекс, поскольку button учитывается как tab.

Вам необходимо получить оригинал mat-tab-group с помощью:

@ViewChild('tabGroup', {static: false}) tab: MatTabGroup;

и установите нужный вам индекс:

this.tab.selectedIndex = this.tabs.length - 1;

Вы можете заметить, что я поместил все это в setTimeout. Это для Angular ловушек жизненного цикла , setTimeout запускает новый цикл Angular.

Вот ваш рабочий StackBlitz .

Код:

src / app / app.component. html

<mat-tab-group [(selectedIndex)]="selectedIndexBinding" #tabGroup>
  <mat-tab *ngFor="let tab of tabs">
    <ng-template mat-tab-label>
      {{ tab }}
    </ng-template>
  </mat-tab>
  <mat-tab disabled>
      <ng-template mat-tab-label>
        <button mat-icon-button (click)="addTab($event)">
          +
        </button>
      </ng-template>
  </mat-tab>
</mat-tab-group>

selectedIndex: {{ tabGroup.selectedIndex }}<br />
selectedIndexBinding: {{ selectedIndexBinding }}

src / app / app .component.ts

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

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {
  @ViewChild('tabGroup', {static: false}) tab: MatTabGroup;
  public selectedIndexBinding = 0;
  public tabs = [];

  public addTab(e: Event) {
    this.tabs.push("Tab");
    e.preventDefault();

    setTimeout(() => {
      console.log(this.tabs, this.tab.selectedIndex);
      this.tab.selectedIndex = this.tabs.length - 1;
    });
  }
}
...