I have an app with three pages: login, settings and main. For each page i have an own lazy loaded module. The main page has an own router outlet to render a sub page.
Now i want to reuse the main page when the sub page changes. But when i go e.g. to the settings page i want to destroy the main page.
How can i implement a custom route reuse strategy that allows the wanted behaviour above?
I've tried something like this (see below) but that causes that my main page gets reused even when i navigate to settings page.
The routing of my app looks like:
const routes: Route[] = [
{
path: '',
data: { shouldReuse: false },
children: [
{
path: 'login',
data: { shouldReuse: false },
loadChildren: () => import('@my-feature-login-page').then(m => m.FeatureLoginPageModule)
},
{
path: '',
canActivate: [
AuthGuardService
],
data: { shouldReuse: false },
loadChildren: () => import('@my-feature-main-page').then(m => m.FeatureMainPageModule)
},
{
path: 'settings',
canActivate: [
AuthGuardService
],
data: { shouldReuse: false },
loadChildren: () => import('@my-feature-settings-page').then(m => m.FeatureSettingsPageModule)
}
]
}
];
And the routing of my main page looks like:
const routes: Route[] = [
{
path: '',
component: MainPageComponent,
data: { shouldReuse: true },
children: [
{
path: '' ,
pathMatch: 'full',
data: { shouldReuse: false },
redirectTo: 'screen/Home'
},
{
path: 'screen/:id' , component: SubPageComponent,
data: { shouldReuse: false }
}
]
}
];
And here is my CustomRouteReuseStrategy:
export class CustomRouteReuseStategy implements RouteReuseStrategy {
handlers: { [key: string]: DetachedRouteHandle } = {};
/**
* Determines if this route (and its subtree) should be detached to be reused later.
* Check the route.routeConfig.path to see if it is a path you would like to store.
* On returning true, store() is fired.
*
* @param {ActivatedRouteSnapshot} route
* @return {*} {boolean}
* @memberof CustomRouteReuseStategy
*/
shouldDetach(route: ActivatedRouteSnapshot): boolean {
return route.data.shouldReuse ?? false;
}
/**
* Stores the detached route for later attachment.
*
* @param {ActivatedRouteSnapshot} route
* @param {(DetachedRouteHandle | null)} handle
* @return {*} {void}
* @memberof CustomRouteReuseStategy
*/
store(route: ActivatedRouteSnapshot, handle: DetachedRouteHandle | null): void {
if (!route.routeConfig.path || !handle) { return; }
this.handlers[route.routeConfig.path] = handle;
}
/**
* Determines whether or not there is a stored route and, if there is, whether or not
* it should be reattached/rendered in place of requested route.
*
* Return true if we have a stored route object for the next route
*
* @param {ActivatedRouteSnapshot} route The route the user requested
* @return {*} {boolean} indicating whether or not to render the stored route
* @memberof CustomRouteReuseStategy
*/
shouldAttach(route: ActivatedRouteSnapshot): boolean {
return !!route.routeConfig && !!this.handlers[route.routeConfig.path];
}
/**
* Finds the locally stored instance of the requested route, if it exists, and returns it
*
* @param {ActivatedRouteSnapshot} route New route the user has requested
* @return {*} {(DetachedRouteHandle | null)} object which can be used to render the component
* @memberof CustomRouteReuseStategy
*/
retrieve(route: ActivatedRouteSnapshot): DetachedRouteHandle | null {
return this.handlers[route.routeConfig.path] ?? null;
}
/**
* Reuse the route if we're going to and from the same route.
*
* If true is returned, then the router actually reuses the route you're currently on and none
* of the other methods are fired. Just return false if the user is navigating away.
*
* @param {ActivatedRouteSnapshot} future The route the user is going to, as triggered by the router
* @param {ActivatedRouteSnapshot} curr The route the user is currently on
* @return {*} {boolean} basically indicating true if the user intends to leave the current route
* @memberof CustomRouteReuseStategy
*/
shouldReuseRoute(future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot): boolean {
return future.data.shouldReuse ?? future.routeConfig === curr.routeConfig;
}
}
How can i reuse the main page only when the sub page changes but not when i navigate out of the main module?