web-dev-qa-db-fra.com

Changer dynamiquement les onglets dans Ionic 2

Je crée une application ionique où j'utilise des onglets. Je souhaite pouvoir naviguer d'un onglet à l'autre à l'aide de la classe de composant TypeScript attachée au modèle d'onglet. Par exemple, l'onglet 2 doit être activé lors du déclenchement d'un événement dans l'onglet 1.

Mon onglet se charge bien dans les onglets et tout va bien tant que je clique manuellement sur l'onglet pour me déplacer, mais essayer de changer de contexte dans le code est très délicat.

Au moment du chargement, je peux activer n'importe quel onglet en définissant simplement l'attribut [selectedIndex] des ion-tabs sur la valeur d'un attribut de la classe de composant mes onglets.

Modèle de parent pour les onglets - tab.html

<ion-tabs #tabParent [selectedIndex]="tabToShow">
  <ion-tab tabTitle="Tab 1" [root]="tab2" [rootParams]="{parent : tabParent}"></ion-tab>
  <ion-tab tabTitle="Tab 2" [root]="tab2" [rootParams]="{parent : tabParent}></ion-tab>
  <ion-tab tabTitle="Tab 3" [root]="tab3" [rootParams]="{parent : tabParent}></ion-tab>
</ion-tabs>

Composant - tab.ts

import {Page} from 'ionic-angular';
import {Tab1} from '../tab1/tab1.ts';
import {Tab2} from '../tab2/tab2.ts';
import {Tab3} from '../tab3/tab3.ts';

@Page({
templateUrl : 'build/pages/tab/tab.html'
})

export class Tab{

tab1: any;
tab2: any;
tab3: any;

tabToShow : number = 1;

ngOnInit(){
 this.tab1 = Tab1;
 this.tab2 = Tab2;
 this.tab3 = Tab3;
 }

}

Dans le composant du premier onglet (Tab1), je peux obtenir une référence aux onglets parents en utilisant [rootParams] = "{parent : tabParent}" et je peux accéder à toutes les propriétés disponibles exposées par l'objet tabs. Un événement généré sur le modèle tab1.html provoque l'appel de goToTab2(). Ainsi, j'ai pu définir SelectedIndex sur 1 (ce qui, je pense, devrait changer l'onglet actif au deuxième). Mais l'onglet ne change pas.

tab1.ts

import {Page, NavParams} from 'ionic-angular';
import {Tab2} from '../tab/tab2/tab2.ts'

@Page({
 templateUrl : 'build/pages/tab/tab1/tab1.html'
})

export class Tab1{

parent : any;

constructor(nav : NavParams){
this.parent = nav.data;
}

goToTab2(event, value): void{
 this.parent.parent.selectedIndex = 1;
 console.log(this.parent.parent);
 }

}

J'ai besoin d'aide, qu'est-ce que je fais mal?

17
oladejo sola

J'ai eu le même problème et après des heures d’essais et de débogage, cela s’est avéré si simple: 

import {Page, NavController, Tabs} from 'ionic-angular';

@Page({
 templateUrl : 'build/pages/tab/tab1/tab1.html'
})

export class Tab1{
    constructor(private nav: NavController) {
    };
    selectTab(index: number) {
        var t: Tabs = this.nav.parent;
        t.select(index);
    }
}
29
Roy S.
this.nav.parent.select(tabIndex); 

tabIndex commence à 0

11
Jagraj Singh

Pour Ionic 3+, vous n'avez pas accès à this.nav. Vous pouvez donc utiliser une fonction telle que:

go(tabIndex: number)
{
    this.app.getActiveNavs()[0].parent.select(tabIndex);
}

Si la fonction est définie dans une classe commune (importée dans toutes vos pages), vous pouvez alors l'appeler où vous voulez:

<button ion-button (click)="core.go(0);">Go to first tab (#0)</button>
<button ion-button (click)="core.go(1);">Go to second tab (#1)</button>
5
Yvan

Je voulais accéder aux pages à onglets à partir d'un menu latéral. Pour permettre cela j'ai fait ce qui suit:

Tabs.html:

<ion-tabs selectedIndex="{{activeTab}}">
  <ion-tab [root]="tab1Root" tabTitle="Home" tabIcon="home"></ion-tab>
  <ion-tab [root]="tab2Root" tabTitle="Profiles" tabIcon="filing">     </ion-tab>
</ion-tabs>

Tabs.ts

...normal stuff preceding ...
export class TabsPage {
 @ViewChild('page-tabs') tabRef: Tabs;
 activeTab: any;
 tab1Root: any = HomePage;
 tab2Root: any = ProfilesPage;

 constructor(public navCtrl: NavController, public params: NavParams) {
    this.authUser = params.get("authUser");
    this.activeTab = params.get("tab")?params.get("tab"):0;
 } 

}

Ensuite, je viens de passer le paramètre tab de app.component.ts 

...normal stuff preceding ...
export class MyApp {
 @ViewChild(Nav) nav: Nav;
 isAppInitialized: boolean = false;
 rootPage: any
 pages: Array<{title: string, type: string, index?: number, component?: any}>;

  constructor(
   private platform: Platform,
   public menu: MenuController) {

 }

 ngOnInit() {
    this.platform.ready().then(() => {
     this.pages = [
       {title: 'Home', type: 'tab', index: 0},
       {title: 'Profiles', type: 'tab', index:1},
       {title: 'Create Shares', type: 'page', component: HomePage},
       {title: 'Existing Shares',type: 'page', component: ProfilesPage}
     ];
    });
  }

 openPage(page) {
   this.menu.close();

   if (page.type==='tab') {
     this.nav.setRoot(TabsPage,{tab: page.index});
   } else {
     this.nav.setRoot(page.componenet);
   }
}

}

Puis dans app.html

 <ion-header>
    <ion-toolbar>
      <ion-title>Left Menu</ion-title>
        <button class="absolute-right" ion-button clear menuClose="left">
          <span ion-text showWhen="ios">Close</span>
          <ion-icon name="md-close" showWhen="Android,windows"></ion-icon>
      </button>
    </ion-toolbar>
  </ion-header>

  <ion-content>
    <ion-list>
      <button ion-item *ngFor="let p of pages" (click)="openPage(p)">
        {{p.title}}
      </button>
    </ion-list>
  </ion-content>
</ion-menu>

Voilà...

5
Eric G

Encore plus facile maintenant! Vous pouvez ajouter l'attribut selectedIndex à 

<ion-tabs selectedIndex="2">
  <ion-tab [root]="tab1Root"></ion-tab>
  <ion-tab [root]="tab2Root"></ion-tab>
  <ion-tab [root]="tab3Root"></ion-tab>
</ion-tabs>
3
Aaron Klaser
export class Page1 {
  tab:Tabs;

  // create a class variable to store the reference of the tabs

  constructor(public navCtrl: NavController, private nav: Nav) {
    this.tab = this.navCtrl.parent;

    /*Since Tabs are declarative component of the NavController 
      - it is accessible from within a child component. 
      this.tab - actually stores an array of all the tabs defined 
      in the tab.html / tab component.
   */
  }

  goToTab2 (){  
    this.tab.select(1);

  //  the above line is self explanatory. We are just calling the select() method of the tab
  }
  goToTab3 (){
    this.tab.select(2);
  }
}
1
Arup Bhattacharya

Dans votre composant tab1 (tab1.ts), essayez d'injecter le composant parent Tab:

export class Tab1{
  constructor(@Host() _parent:Tab) {}
  goToTab2(event, value): void{
    this._parent.tabToShow = 1 ;
  }
}
0
Michael Desigaud

Vous pouvez obtenir un élément tabs en utilisant @ViewChild ou IonicApp.getComponent(). Le bouton de tabulation est accessible en passant par l’élément de tabulation . L’événement de clic de bouton de tabulation est lié à onClick fonction par using @HostListener. Vous pouvez changer d’onglet en appelant le bouton onClick.

export class TabsPage {
  tab1TabRoot: Type = Tab1Page;
  tab2TabRoot: Type = Tab2Page;
  tab3TabRoot: Type = Tab3Page
  @ViewChild(Tabs) tabs;

  constructor(
    private _ngZone: NgZone,
    private _platform: Platform,
    private _app: IonicApp,
  ) {
  }

  ngOnInit() {
  }

  ngAfterViewInit() {
    console.log(this.tabs);
  }

  public selectTab2() {
    this._ngZone.run(function() {
      tabs._btns._results[0].onClick();
    });
  }
}
0
jccf091

Son simple suffit d'utiliser la classe NavController et sa propriété .parent.select (la position de l'onglet que vous voulez)

constructor(public navCtrl: NavController) {
}
goToTab2(){
    this.navCtrl.parent.select(1);
}
0
Nitish Patil