0

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. enter image description here

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?

Daniel
  • 153
  • 1
  • 10

0 Answers0