web-dev-qa-db-fra.com

Mat-tab material angular6 selectedIndex ne fonctionne pas avec * ngFor

J'affiche plusieurs onglets avec une boucle ngPour utiliser Angular Material tabs. Cela fonctionne correctement mais maintenant je voudrais ouvrir le deuxième onglet une fois initialisé et non le premier onglet. Par conséquent, j'ajoute la propriété selectedIndex dans le groupe mat-tab, mais cela ne fonctionne pas et continue de s'ouvrir sur le premier onglet.

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>

La variable "tabs" est récupérée avec un service du serveur dans ngOnInit comme ceci:

COMPOSANT

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

Je pense que ça vient d'ici parce que si je mets les onglets manuellement sans demander au serveur ça marche. Comme ça:

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

Vous pouvez définir le selectedIndex une fois vos données de service disponibles. Vous devez effectuer les modifications ci-dessous:

  1. Obtenez une référence à l'occurrence MatTabGroup dans votre composant (le composant dont le modèle contient mat-tab-group) en déclarant l'attribut ci-dessous:

    @ViewChild(MatTabGroup) tabGroup: MatTabGroup;
    
  2. Définissez ensuite le selectedIndex dans l'appel de méthode subscribe tout en mettant à jour la nouvelle valeur pour tabs

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

Dans l'ensemble, votre composant peut ressembler à ci-dessous:

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);
      }
    );
  }
}
8
Wand Maker

<mat-tab-group> lit uniquement le [selectedIndex] entrée lors de la création du composant. Ensuite, la liaison de sortie (selectedIndex) vous permet de suivre les modifications apportées aux onglets.

Je pense que vous définissez la valeur 1 avant que cet onglet n'existe.

Le problème est que *ngFor crée les enfants mat-tab composants ensuite. Quand <mat-tab-group> est averti que les enfants ont changé. Par défaut, il s'agit du premier onglet .

La seule solution de contournement que je connaisse est de déclencher une modification du [selectedIndex] liaison après l'enfant <mat-tab> des composants ont été créés.

Mettez à jour votre composant pour avoir une propriété:

public selectedIndex: number = 0;

Utilisez ceci comme liaison pour l'entrée selectedIndex:

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

Injectez ces dépendances dans votre composant:

  public constructor(private change: ChangeDetectorRef) {}

Mettez à jour votre abonnement pour changer l'index sélectionné après le *ngFor a terminé la mise à jour du document.

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();
    });
});
6
Reactgular