Disabling Tabs in Ionic
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.