web-dev-qa-db-fra.com

Comment sélectionner l'onglet NgbTabset comme actif au chargement?

L'exemple "Sélectionnez un onglet actif par id" dans https://ng-bootstrap.github.io/#/components/tabs montre comment utiliser un bouton DOM pour sélectionner par programme un onglet Bootstrap Angular. être actif. Mais comment définir un onglet pour qu'il soit actif à partir du code TypeScript - par exemple, en référençant un état persistant de quel onglet a été ouvert le plus récemment sur cette vue à l'aide d'un service qui stockait cet état?

La documentation activeId sur cette page explique comment coder en dur un onglet pour qu'il soit actif, mais je dois définir le choix de l'onglet par programme. Je peux définir l'onglet à l'aide de [activeId] = getActiveId () (où getActiveId () accède à un service dans lequel je peux stocker la valeur de l'onglet), mais cela pose de nombreux problèmes lorsque l'actifId est défini, ce qui est sans doute la raison pour laquelle la documentation indique "Utilisez la méthode" select "pour basculer un onglet par programme".

En suivant cette direction, j'ai essayé d'utiliser select sur le ngb-tabset et d'utiliser l'événement html onload pour résoudre ce problème dans le DOM, mais je ne savais pas exactement où placer onload et je ne pouvais pas le faire fonctionner.

J'ai essayé d'utiliser ngOnInit dans TypeScript pour définir l'état du DOM, mais je ne savais pas comment faire référence au ngb-tabset. 

Quel est un bon moyen de coordonner entre le TypeScript et le DOM pour sélectionner l'onglet NgbTabset comme actif au chargement? 

5
Mickey Segal

J'ai compris comment faire fonctionner cela, mais je ne sais pas s'il s'agit d'une solution de contournement ou d'une solution élégante.

J'ai fini par aller à l'encontre du conseil de https://ng-bootstrap.github.io/#/components/tabs/api , qui disait "Utilisez la méthode" select "pour changer d'onglet par programme". J'ai utilisé activeId, le code principal étant:

<ngb-tabset [activeId]="activeIdString">

[activeId] se lie à une variable activeIdString, et non à une méthode comme celle décrite dans le message d'origine (l'utilisation d'une méthode getActiveId () au lieu d'une variable entraîne le message d'erreur "L'expression a été modifiée après vérification"). Une erreur en mode de développement uniquement, comme décrit à l’adresse https://github.com/angular/angular/issues/6005 , pose toujours un problème.) 

La variable activeIdString est définie à l'initialisation du composant:

  ngOnInit(): void {
    this.activeIdString = this.tabNameString[this.personService.getNextTab()];
  }

Puisque ce code est sur le composant avec les onglets, j’enregistre mostRecentTab sur ce composant et le convertis en nextTab sur le composant de navigation avant d’atteindre le composant avec des onglets, éliminant ainsi le besoin de prêter attention au moment exact où ngOnInit s’exécute par rapport à quand J'enregistre mostRecentTab.

Une discussion "Impossible de sélectionner un onglet par programme" à https://github.com/ng-bootstrap/ng-bootstrap/issues/1016 suggère également d'utiliser activeId. Je suis donc confiant de ne pas tenir compte des conseils de https. : //ng-bootstrap.github.io/#/components/tabs/api à "Utilisez la méthode" select "pour basculer un onglet par programme".

7
Mickey Segal

Je viens d'accomplir cette chose exacte avec l'accordéon ngb. 

L'accordéon ressemble à ceci:

<ngb-accordion #acc="ngbAccordion" activeIds="ngb-panel-0" [closeOthers]="true">

  <ngb-panel id="static-1" title="First panel">
    <ng-template ngbPanelTitle>
        <button type="button" class="btn" data-toggle="button">
               Tab One
         </button>
    </ng-template>
    <ng-template ngbPanelContent>
         Tab One Content
    </ng-template>
  </ngb-panel>

  <ngb-panel id="static-2" title="Second">
    <ng-template ngbPanelTitle>
        <button type="button" class="btn" data-toggle="button">
              Tab Two
         </button>
    </ng-template>
    <ng-template ngbPanelContent>
         Tab Two Content
    </ng-template>
  </ngb-panel>

</ngb-accordion>

Je configure l'onglet en tant qu'observable dans un service d'état (stateSvc), puis je m'y abonne dans mon composant. Ainsi, lorsque je quitte un formulaire et que je souhaite revenir à l'onglet users-manage, par exemple, J'ai défini stateSrv.this.currentAccordianTab = 'users-manage' puis je navigue vers le composant avec l'accordian. 

@ViewChild me donne une référence au ngb-accordéian dans le modèle par sa référence de modèle (#acc)

Dans ma classe, j'ai ceci:

@ViewChild('acc') acc;

currentAccordianTab: string;

ngAfterContentInit() {
    this.stateSvc.currentTab$
        .subscribe(response => {
            this.currentAccordianTab = response;
            if (this.currentAccordianTab = 'users-manage') {
                this.acc.toggle('static-2');
            } else {
                this.acc.toggle('static-1');
            }
        });
}

Sur le ngb-accordéian, il existe une méthode de basculement qui utilise un paramètre tab-id pour définir l'onglet actuel. Je suppose que la méthode select est l’équivalent du ngb-tabset, mais vous pouvez consulter la documentation de l’API.

En gros, nous obtenons une référence au ngb-accordéian avec @ViewChild, puis nous appelons sa fonction de bascule this.acc.toggle('static-2'); pour définir l'état sur l'onglet correctement visible.

1
Stephen R. Smith