Issue
I am developing a pwa in ionic/angular and I have a problem with tabs using the pwa from Android. Basically there are 3 tabs: Home | Shopping | Favourites
Each tab then contains subpaths . The problem is that if for example I am in Home/about and I click on Shopping, then I click on home again, then Shopping etc several times . This results in new states being entered in window.history and if I use the Android hardware back button it makes me navigate between home/about and Shopping several times. Instead I would like the following case: if I am in Shopping I go back to home/about, then home and then the app closes. Is this feasible? I have tried using both skipLocationChange and replaceUrl of the router object, for example:
export class TabsPage {
constructor(private router: Router) {}
goToShopping(){
this.router.navigate(["/tabs/shopping"], {replaceUrl: true})
}
}
Tabs template:
<ion-tabs>
<ion-tab-bar slot="bottom" (click)="goToHome()">
<ion-tab-button tab="home">
<ion-icon name="home"></ion-icon>
<ion-label>Home</ion-label>
</ion-tab-button>
<ion-tab-button tab="shopping" (click)="goToShopping()">
<ion-icon name="card"></ion-icon>
<ion-label>Shopping</ion-label>
</ion-tab-button>
<ion-tab-button tab="favourites" (click)="goToFavourites()">
<ion-icon name="star"></ion-icon>
<ion-label>Favourites</ion-label>
</ion-tab-button>
</ion-tab-bar>
</ion-tabs>
With this, however, if I am in Home/About and then click on the Shopping tab and press the hardware back button it goes to Home because it rightly replaces the current state of About with Shopping
Solution
As you already discovered, Ionic uses the embedded WebView history by default when pressing the hardware back button and implementing the desired behavior directly on the webview history would require a lot of changes in the routing mechanism.
To have a "simple" handling of the back button, you may watch the popstate
event in a Router
instance of your app.component.ts
. But note that this will be called any navigation, as the pages call this popstate when going forward as well, so handle with care.
app.component.ts
constructor(private router: Router) {
//firstly, we'll need to trick the browser history on every view created
this._app.viewDidEnter.subscribe((app) => {
history.pushState (null, null, "");
});
this.router.events.subscribe((event: any): void => {
if (event instanceof NavigationStart) {
if (event.navigationTrigger === 'popstate') {
// Navigation was triggered
}
}
}
}
For those running on native platforms using capacitor, there's a Platform
event you can listen to and decide if you want to override the default behavior or not. The example in the official docs is as follows:
import { Platform } from '@ionic/angular';
/// ...
constructor(private platform: Platform) {
this.platform.backButton.subscribeWithPriority(10, (nextHandler) => {
// do some logic validation here
// ...
// if you do not need a custom behavior and want the framework
// to handle the back button normally, just call the nextHandler() parameter
nextHandler();
});
}
You can find more examples and detailed explanations on the official documentation for Hardware Back Button
Also, for PWA, there's a previous question (for ionic 3) that may help finding a suitable solution for you:
How to handle hardware back button in PWA developed using Ionic3
Answered By - Leu
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.