mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-16 18:17:31 +08:00
fix(tabs): preserve route navigation extras when changing tabs (#18493)
fixes #18717
This commit is contained in:

committed by
Liam DeBeasi

parent
b3b3312711
commit
4c8f32fae9
@ -242,6 +242,22 @@ export class IonRouterOutlet implements OnDestroy, OnInit {
|
||||
return active ? active.url : undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the RouteView of the active page of each stack.
|
||||
* @internal
|
||||
*/
|
||||
getLastRouteView(stackId?: string): RouteView | undefined {
|
||||
return this.stackCtrl.getLastUrl(stackId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the root view in the tab stack.
|
||||
* @internal
|
||||
*/
|
||||
getRootView(stackId?: string): RouteView | undefined {
|
||||
return this.stackCtrl.getRootUrl(stackId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the active stack ID. In the context of ion-tabs, it means the active tab.
|
||||
*/
|
||||
@ -315,7 +331,7 @@ class OutletInjector implements Injector {
|
||||
private route: ActivatedRoute,
|
||||
private childContexts: ChildrenOutletContexts,
|
||||
private parent: Injector
|
||||
) {}
|
||||
) { }
|
||||
|
||||
get(token: any, notFoundValue?: any): any {
|
||||
if (token === ActivatedRoute) {
|
||||
|
@ -66,18 +66,53 @@ export class IonTabs {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* When a tab button is clicked, there are several scenarios:
|
||||
* 1. If the selected tab is currently active (the tab button has been clicked
|
||||
* again), then it should go to the root view for that tab.
|
||||
*
|
||||
* a. Get the saved root view from the router outlet. If the saved root view
|
||||
* matches the tabRootUrl, set the route view to this view including the
|
||||
* navigation extras.
|
||||
* b. If the saved root view from the router outlet does
|
||||
* not match, navigate to the tabRootUrl. No navigation extras are
|
||||
* included.
|
||||
*
|
||||
* 2. If the current tab tab is not currently selected, get the last route
|
||||
* view from the router outlet.
|
||||
*
|
||||
* a. If the last route view exists, navigate to that view including any
|
||||
* navigation extras
|
||||
* b. If the last route view doesn't exist, then navigate
|
||||
* to the default tabRootUrl
|
||||
*/
|
||||
@HostListener('ionTabButtonClick', ['$event.detail.tab'])
|
||||
select(tab: string) {
|
||||
const alreadySelected = this.outlet.getActiveStackId() === tab;
|
||||
const href = `${this.outlet.tabsPrefix}/${tab}`;
|
||||
const url = alreadySelected
|
||||
? href
|
||||
: this.outlet.getLastUrl(tab) || href;
|
||||
const tabRootUrl = `${this.outlet.tabsPrefix}/${tab}`;
|
||||
if (alreadySelected) {
|
||||
const rootView = this.outlet.getRootView(tab);
|
||||
const navigationExtras = rootView && tabRootUrl === rootView.url && rootView.savedExtras;
|
||||
return this.navCtrl.navigateRoot(tabRootUrl, {
|
||||
...(navigationExtras),
|
||||
animated: true,
|
||||
animationDirection: 'back',
|
||||
});
|
||||
} else {
|
||||
const lastRoute = this.outlet.getLastRouteView(tab);
|
||||
/**
|
||||
* If there is a lastRoute, goto that, otherwise goto the fallback url of the
|
||||
* selected tab
|
||||
*/
|
||||
const url = lastRoute && lastRoute.url || tabRootUrl;
|
||||
const navigationExtras = lastRoute && lastRoute.savedExtras;
|
||||
|
||||
return this.navCtrl.navigateRoot(url, {
|
||||
animated: true,
|
||||
animationDirection: 'back'
|
||||
});
|
||||
return this.navCtrl.navigateRoot(url, {
|
||||
...(navigationExtras),
|
||||
animated: true,
|
||||
animationDirection: 'back',
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
getSelected(): string | undefined {
|
||||
|
@ -70,7 +70,7 @@ export class StackController {
|
||||
if (router.getCurrentNavigation) {
|
||||
currentNavigation = router.getCurrentNavigation();
|
||||
|
||||
// Angular < 7.2.0
|
||||
// Angular < 7.2.0
|
||||
} else if (
|
||||
router.navigations &&
|
||||
router.navigations.value
|
||||
@ -191,6 +191,14 @@ export class StackController {
|
||||
return views.length > 0 ? views[views.length - 1] : undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
getRootUrl(stackId?: string) {
|
||||
const views = this.getStack(stackId);
|
||||
return views.length > 0 ? views[0] : undefined;
|
||||
}
|
||||
|
||||
getActiveStackId(): string | undefined {
|
||||
return this.activeView ? this.activeView.stackId : undefined;
|
||||
}
|
||||
|
Reference in New Issue
Block a user