Mat-tab material angular6 selectedIndex 不适用于 *ngFor

Mat-tab material angular6 selectedIndex doesn't work with *ngFor

我使用 Angular Material 选项卡显示几个带有循环 ngFor 的选项卡。 这工作正常但是现在我想在初始化时打开第二个选项卡而不是第一个选项卡。 因此,我在 mat-tab-group 中添加了 属性 selectedIndex 但它不起作用并且仍然继续在第一个选项卡上打开。

HTML

<mat-tab-group class="col-10 offset-1" (selectedTabChange)="onTabChanged($event)" [selectedIndex]="1">
  <mat-tab label={{tab.name}} *ngFor="let tab of tabs; let index = index">
    <div>
      Values: {{tab.values}}
    </div>
  </mat-tab>
</mat-tab-group>

变量 "tabs" 在 ngOnInit 中通过服务从服务器获取,如下所示:

组件

this.api.getDataset(this.route.snapshot.params["experimentid"]).subscribe(
  res => {
    this.tabs = res;
  },
  err => {
    console.log(err);
  }
);

我认为它来自这里,因为如果我在不请求服务器的情况下手动设置选项卡,它就可以工作。像这样:

this.tabs = [{name: "X2", values: "52"}, {name: "Z2", values: "52"}, {name: "R2", values: "52"}]

<mat-tab-group> 仅在首次创建组件时读取 [selectedIndex] 输入。之后输出绑定 (selectedIndex) 让您跟踪选项卡更改。

我认为您在该选项卡存在之前设置值 1

问题是 *ngFor 之后创建了 children mat-tab 组件。当 <mat-tab-group> 收到 children 已更改的通知时,它默认为 第一个 选项卡。

我所知道的唯一 work-around 是触发对 [selectedIndex] 绑定的更改 child <mat-tab> 组件已创建。

更新您的组件以获得 属性:

public selectedIndex: number = 0;

将其用作 selectedIndex 输入的绑定:

<mat-tab-group class="col-10 offset-1" 
               (selectedTabChange)="onTabChanged($event)" 
               [selectedIndex]="selectedIndex">

将这些依赖项注入您的组件:

  public constructor(private change: ChangeDetectorRef) {}

*ngFor 完成文档更新后更新您的订阅以更改所选索引。

this.api.getDataset(this.route.snapshot.params["experimentid"]).subscribe(res => {
    this.tabs = res;
    // wait for ngFor to finish
    window.setTimeout(()=>{
       this.selectedIndex = 1;
       this.change.markForCheck();
    });
});

您可以在服务数据可用后设置selectedIndex。您需要进行以下更改:

  1. 通过声明以下属性获取对组件(其模板包含 mat-tab-group 的组件)中 MatTabGroup 实例的引用:

    @ViewChild(MatTabGroup) tabGroup: MatTabGroup;
    
  2. 然后在 subscribe 方法调用中设置 selectedIndex,同时更新 tabs

    的新值
    .subscribe(
      res => {
        this.tabs = res;
        this.tabGroup.selectedIndex = 1;
      },
    

总体而言,您的组件可能如下所示:

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

@Component({
  selector: 'tab-group-basic-example',
  templateUrl: 'tab-group-basic-example.html',
  styleUrls: ['tab-group-basic-example.css'],
})
export class TabGroupBasicExample implements OnInit {

  @ViewChild(MatTabGroup) tabGroup: MatTabGroup;

  tabs = [];

  ngOnInit() {
    this.api.getDataset(experimentId).subscribe(
      res => {
          this.tabs = res;
          this.tabGroup.selectedIndex = 1;
      },
      err => {
          console.log(err);
      }
    );
  }
}