Материал вкладки матовый angular6 selectedIndex не работает с *ngFor

Я отображаю несколько вкладок с циклом ngFor, используя вкладки Angular Material. Это работает правильно, однако теперь я хотел бы открыть вторую вкладку при инициализации, а не первую вкладку. Поэтому я добавляю свойство selectedIndex в группу mat-tab-group, но оно не работает и продолжает открываться на первой вкладке.

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"}]

2 ответа

Решение

Вы можете установить selectedIndex после того, как ваши данные службы доступны. Вам необходимо сделать следующие изменения:

  1. Получить ссылку на MatTabGroup экземпляр в вашем компоненте (компонент, чей шаблон содержит mat-tab-group) объявив атрибут ниже:

    @ViewChild(MatTabGroup) tabGroup: MatTabGroup;
    
  2. Затем установите selectedIndex в subscribe вызов метода при обновлении нового значения для 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);
      }
    );
  }
}

<mat-tab-group> только читает [selectedIndex] ввод при первом создании компонента. После этого выходная привязка (selectedIndex) позволяет отслеживать изменения вкладок.

Я думаю, что вы устанавливаете значение 1 до того, как эта вкладка существует.

Проблема в том, что *ngFor создает детей mat-tab компоненты потом. когда <mat-tab-group> уведомляется, что дети изменили его по умолчанию на первую вкладку.

Единственный обходной путь, о котором я знаю, - это вызвать изменение [selectedIndex] обязательный после ребенка <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, private zone: NgZone) {}

Обновите подписку, чтобы изменить выбранный индекс после *ngFor закончил обновление документа.

this.api.getDataset(this.route.snapshot.params["experimentid"]).subscribe(res => {
    this.tabs = res;
    // wait for ngFor to finish
    window.setTimeout(()=>{
        // run inside Angular
        this.zone.run(()=>{ 
           this.selectedIndex = 1;
           // force change detection
           this.change.detectChanges();
        });
    });
});
Другие вопросы по тегам