Modify ionic-conference-app so that we can move between two different sets of tabs

I’m using Ionic 3.8.1 and testing in Google Chrome.

http://ionic-team.github.io/ionic-conference-app was my starting point and everything works well.

However for my app, when the user clicks a “list item” e.g. a speaker on the Speakers page, I need the “detail” page (e.g. Speaker Detail) to have its own set of tabs, for example:

  • Info
  • Hobbies
  • Other events
  • More

So, the main/global tabs on the site are “Schedule”, “Speakers”, “Map” and “About”, but when the user clicks on an individual speaker from the speaker list page, those tabs should disappear and be replaced at the bottom by “Info”, “Hobbies”, “Other events” and “More”.

Note that this is not just switching to a new set of tabs in a “dumb” way. The default tab/page (“Info”) of the new tabs-set must be passed the speakerId in order for the page to display the information about the relevant speaker.

I think this is quite a common pattern in modern apps: one set of “main” tabs for main navigation, then “item-specific” tabs on an “item details” page. The user can do what they need to do in the “item details” area then return back to the main tabs.

To achieve this I started by generating a second tabs page - let’s call it speaker-tabs-page - consisting of:

  • speaker-tabs-page.html;
  • speaker-tabs-page.scss; and
  • speaker-tabs-page.ts.

And my speaker-tabs-page.html looks like this:

<ion-tabs [selectedIndex]="mySelectedIndex" name="speaker">
  <ion-tab [root]="tab1Root" [rootParams]="speakerParams" tabTitle="Info" tabIcon="filing"></ion-tab>
  <ion-tab [root]="tab2Root" tabTitle="Hobbies" tabIcon="filing"></ion-tab>
  <ion-tab [root]="tab3Root" tabTitle="Other" tabIcon="filing"></ion-tab>
</ion-tabs>

In app.module.ts, my entry in the DeepLinker config array looks like this:
{ component: SpeakerDetailPage, name: 'SpeakerDetail', segment: 'speakerDetail/:speakerId' },

In speaker-list.ts, the goToSpeakerDetail() function looks like this:

goToSpeakerDetail(speaker: any) {
    const root = this._app.getRootNav();
    root.setRoot(SpeakerTabsPage, { speakerId: speaker.id });
}

As you can see, my approach has been to remove the main tabs and bring in the new tabs by changing the root navigation context using setRoot() on the RootNav.

I’m also trying to ensure the “speakerId” parameter gets passed through to the default tab in speaker-tabs by using rootParams binding in the SpeakerTabsPage component and template.

However, at the moment I can’t get things to fully work.

Strangely, what’s happening is that when the user clicks a speaker on the “Speakers” page (address http:/…/#/tabs-page/speakers/speakerList) the tabs at the bottom are changed successfully but the main body of the page does not change to the speaker “details” page. Instead it just continues to just show the list of speakers. The URL has changed to: http://…/#/speakers-tabs-page/info/speakerList.

I’ve tried various alternative approaches with popping and pushing the page onto the nav but I’m getting nowhere.

There are quite a few other threads out there on a similar topic but none of them are properly resolved.

I hope that because the starting point is the http://ionic-team.github.io/ionic-conference-app that someone with better ionic skills/knowledge than me could quickly try what I’m trying to do and let me know if it’s impossible… or if it is possible then some help would be very much appreciated!

This is probably a stupid question, but are we sure that mySelectedIndex is initialized to something sane (like 0)?

Yes, my new TabsPage component is pretty much a mirror of the existing TabsPage component, so it has this constructor:

  constructor(navParams: NavParams) {
    this.mySelectedIndex = navParams.data.tabIndex || 0;
  }

So mySelectedIndex is always set to something.

After clicking the list item, my new tabs are there and one of those tabs is selected, it’s just that for some reason the main body of the page does not change from the list page.

Do I maybe also (in addition to setRoot()) need to have the root nav select() a page?

I’ve made some progress!

It seems that you can’t navigate from an item in TabsPage directly to an item in AnotherTabsPage.

That’s why my previous code does not work:

goToSpeakerDetail(speaker: any) {
    const root = this._app.getRootNav();
    root.setRoot(SpeakerTabsPage, { speakerId: speaker.id });
}

But, when I add an intermediate “reset” stage by setting root to a page (LoginPage) which is not in either tabs set and then setRoot to my new tabs set, it works:

goToSpeakerDetail(speaker: any) {
    const root = this._app.getRootNav();
    root.setRoot(LoginPage);
    root.setRoot(SpeakerTabsPage, { speakerId: speaker.id });
}

It feels like a bit of a hack though, and provides a very quick flash of a page (LoginPage) which isn’t actually wanted.
Is there a better/correct way of doing this?