Mat-tab-group [(selectedIndex)]=...绑定不稳定

Mat-tab-group's [(selectedIndex)]=... binding is flaky

我正在使用 Angular 和 MaterialTabs 模块。

我的组件中有一个选项卡列表,我使用 mat-tabs 和 ngFor 显示这些选项卡,另外还有一个带有加号按钮的禁用选项卡。单击加号按钮时,我想添加一个新选项卡并立即关注该选项卡。 (类似于浏览器选项卡的工作方式。)

这是它的样子:

我通过双向 属性 绑定到 mat-tab-group 的 selectedIndex 属性 并在按钮单击事件处理程序中从我的组件中设置它。

你可以看到tabgroup的属性和绑定到它的属性是相等的,当它工作时。

但是,我 运行 遇到了一个问题,如果我刚加载页面并先单击按钮,属性 绑定会以某种方式中断:

在任何选项卡上单击一次似乎可以永远解决该问题。当您重新加载页面时,问题又回来了。

根据我的理解,以下 属性 绑定将确保值始终相等,并且如果其中一个更改,另一个将随之更改:

[(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;
  }
}

您的问题来自您设置新索引的方式,因为 button 在任何方面都算作 tab

您需要通过以下方式检索原始 mat-tab-group

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

然后直接设置你想要的索引:

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

你可能会注意到我把它们都放在了 setTimeout 中。是为了Angular lifecycle hooks,setTimeout触发新的Angular循环。

Here's your working 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;
    });
  }
}