Disabling Tabs in Ionic

June 8th 2018 Ionic 2/3

Quick switching between tabs in Ionic can cause issues when one of the tabs requires a long initialization process every time it is displayed, as for example native Google Maps do. Before the initialization is completed, the user might already leave the tab and then navigate back to it, triggering another initialization in parallel to the first one. One way to avoid the issue is by disabling the switching between tabs until the page initialization is complete.

Tabs in Ionic can be disabled by setting the enabled property for each of the tabs in the page template:

<ion-tabs>
  <ion-tab [root]="tab1Root" tabTitle="Home"
           tabIcon="home" enabled="{{tabsEnabled}}">
  </ion-tab>
  <ion-tab [root]="tab2Root" tabTitle="About"
           tabIcon="information-circle" enabled="{{tabsEnabled}}">
  </ion-tab>
  <ion-tab [root]="tab3Root" tabTitle="Contact"
           tabIcon="contacts" enabled="{{tabsEnabled}}">
  </ion-tab>
</ion-tabs>

In the page component, the corresponding property can be set by a method

tabsEnabled = true;

enableTabs(enable: boolean): void {
    this.tabsEnabled = enable;
}

As described in a previous blog post, there are two different approaches to calling a method of the root tab page from a child tab page.

Calling the Method on the Root Tab Page Directly

The root tab page can be accessed from the child tab page through the NavController:

let tabsPage = (this.navCtrl.parent as Tabs).viewCtrl.instance;

If the page needs to be initialized every time it's entered, the initialization will be triggered inside the ionViewDidEnter lifecycle event. The tabs should be disabled for the duration of the initialization process:

ionViewDidEnter() {
    let tabsPage = (this.navCtrl.parent as Tabs).viewCtrl.instance;
    tabsPage.enableTabs(false);

    this.longRunningInit().then(() => {
        tabsPage.enableTabs(true)
    });
}

Although the approach seems simple, it depends on undocumented properties to access the root tab page. It also only allows child tab pages to enable or disable switching between tabs.

Messaging the Root Tab Page Using Events

Instead of relying on the page navigation internals, Ionic's built-in Events publish-subscribe system can be used. The root tab page needs to subscribe to the topic which will be used for notification:

private tabsEventHandler: (boolean) => void;

constructor(private events: Events) {
    this.tabsEventHandler = enable => this.enableTabs(enable);
}

ionViewDidLoad() {
    this.events.subscribe('tabs.enable', this.tabsEventHandler);
}

ionViewWillUnload() {
    // avoid triggering the event handler after page is unloaded
    this.events.unsubscribe('tabs.enable', this.tabsEventHandler);
}

The child tab page can now publish to this topic to disable the tabs at the start of the initialization and enable them back at the end:

ionViewDidEnter() {
    this.events.publish('tabs.enable', false);

    this.longRunningInit().then(() => {
        this.events.publish('tabs.enable', true);
    });
}

This approach is much more loosely coupled than the previous one and allows other pages and components to enable or disable the tabs as well if necessary.

Copyright
Creative Commons License