Search code examples
angulartypescriptcordovaionic-frameworkcapacitor

How can I restore the state of a tab when switching between them?


Switching between tabs with the implementation of ion-router-outlet loads main page instead of latest page.

If understood it right tab pages should be restored instead of loading their main page and if using the android hardware button they are all contained in the navigation stack. (Did still not understand why I had to add navController.back() to achieve going back with the android hardware button when it should be done automatically as stated here)

Could be same problem as this issue and the related implementation.

I implemented it with ion-router-outlet but also tried it with ion-nav and ion-nav-link but this broke the navigation stacks between the tabs.

Current implementation:

tabs-routing.module.ts

const routes: Routes = [
  {
    path: '',
    component: TabsPage,
    children: [
      {
        path: '',
        redirectTo: 'home',
        pathMatch: 'full'
      },
      {
        path: 'calibration',
        loadChildren: () => import('../tab1/tab1.module').then(m => m.Tab1PageModule)
      },
      {
        path: 'home',
        loadChildren: () => import('../tab2/tab2.module').then(m => m.Tab2PageModule)
      },
      {
        path: 'survey',
        loadChildren: () => import('../tab3/tab3.module').then(m => m.Tab3PageModule)
      }
    ]
  },
];

tabs.page.html

<ion-tabs>
  <ion-tab-bar slot="bottom">
    <ion-tab-button tab="calibration">
      <ion-icon aria-hidden="true" name="eye"></ion-icon>
    </ion-tab-button>

    <ion-tab-button tab="home">
      <ion-icon aria-hidden="true" name="home"></ion-icon>
    </ion-tab-button>

    <ion-tab-button tab="survey">
      <ion-icon aria-hidden="true" name="reader"></ion-icon>
    </ion-tab-button>
  </ion-tab-bar>
</ion-tabs>

tab1-routing.module.ts

const routes: Routes = [
  {
    path: '',
    component: Tab1Page,
    children: [
      {
        path: '',
        redirectTo: 'menu',
        pathMatch: 'full'
      },
      {
        path: 'calibration',
        loadChildren: () => import('./calibration/calibration.module').then(m => m.CalibrationPageModule)
      },
      {
        path: 'menu',
        loadChildren: () => import('./menu/menu.module').then(m => m.MenuPageModule)
      }

    ]
  }
];

tab1.page.html

<ion-content>
  <ion-router-outlet></ion-router-outlet>
</ion-content>

tab1.page.ts

  constructor(private platform: Platform, private navController: NavController) {
    this.platform.backButton.subscribeWithPriority(10, ()=> {
      console.log("Handler called!");
      navController.back();
    });
  }

menu.page.html

<ion-header [translucent]="true">
  <ion-toolbar>
    <ion-title>
      Calibration
    </ion-title>
  </ion-toolbar>
</ion-header>

<ion-content>
  <ion-grid class="ion-align-items-center">
    <ion-row class="ion-justify-content-center">
      <ion-col class="ion-text-center">
          <ion-button routerLink="/calibration/calibration" shape="round">
            Start calibration
            <ion-icon slot="start" name="play"></ion-icon>
          </ion-button>
      </ion-col>
    </ion-row>
    <ion-row class="ion-justify-content-center">
      <ion-col class="ion-text-center">
        <ion-button shape="round">
          Delete calibration
          <ion-icon slot="start" name="trash"></ion-icon>
        </ion-button>
      </ion-col>
    </ion-row>
  </ion-grid>
</ion-content>

I hope someone can help me here. Maybe it is just a quick fix or a misunderstanding in using the wrong things here.


Solution

  • So I fixed it myself by removing the separate files of menu completely and put its content directly in the tab1 files. This seems to fix the issue and is working now on my Android Device.

    I then added this code to my calibration.html to correctly navigate because the normal would brake the navigation st:

    <ion-buttons slot="start" (click)="goBack()">
      <ion-icon slot="icon-only" name="arrow-back"></ion-icon>
    </ion-buttons>
    

    Also this code of tab1.page.ts has to be in app.component.ts:

    constructor(private platform: Platform, private navController: NavController) {
      this.platform.backButton.subscribeWithPriority(10, ()=> {
      console.log("Handler called!");
      navController.back();
    });
    

    }

    And tab1-routing.module.ts now looks like this:

    const routes: Routes = [
      {
        path: '',
        component: Tab1Page,
      },
      {
        path: 'start',
        loadChildren: () => import('../tab1/calibration/calibration.module').then(m => m.CalibrationPageModule)
      }
    ];
    

    The routerlink in tab1.page.html changed to /calibration/start

    Note: My /calibration is the tab1 (I know bit of a bad naming of files, which I will improve in the future)