Custom RouteReuseStrategy for Angular's child module

故事扮演 提交于 2019-11-29 00:29:45

I finally achieved it by passing a bit modified CustomRouteStrategy to AppModule:

export class CustomRouteReuseStrategy extends RouteReuseStrategy {
    public shouldDetach(route: ActivatedRouteSnapshot): boolean { return false; }
    public store(route: ActivatedRouteSnapshot, detachedTree: DetachedRouteHandle): void {}
    public shouldAttach(route: ActivatedRouteSnapshot): boolean { return false; }
    public retrieve(route: ActivatedRouteSnapshot): DetachedRouteHandle { return null; }
    public shouldReuseRoute(future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot): boolean {
        return (future.routeConfig === curr.routeConfig) || future.data.reuse;
    }
}

And adding data: { reuse: true } to the routing of lazily loaded ChildModule:

{
    path: 'some-path',
    data: { reuse: true },
    loadChildren: './child.module#ChildModule',
},

Demo with more advanced solution

Sagar Jadhav

CUSTOM ROUTE STRATEGY

import {RouteReuseStrategy,DetachedRouteHandle,ActivatedRouteSnapshot} from '@angular/router';

export class CustomReuseStrategy implements RouteReuseStrategy {

  public static handlers: { [key: string]: DetachedRouteHandle } = {}

  private static delete: string

  //THIS METHOD IS USED FOR DELETE ROUTE
  public static deleteRouteSnapshot(name: string): void {
      if (CustomReuseStrategy.handlers[name]) {
          delete CustomReuseStrategy.handlers[name];
      } else {
          CustomReuseStrategy.delete = name;
      }
  }

  //THIS METHOD RETURN TRUE WHEN ROUTE REUSE LATER
  public shouldDetach(route: ActivatedRouteSnapshot): boolean {
      return true;
  }

  //THIS METHOD IS USD FOR STORE ROUTE STATE
  public store(route: ActivatedRouteSnapshot, handle: DetachedRouteHandle): void {
      if (CustomReuseStrategy.delete && CustomReuseStrategy.delete == this.getRouteUrl(route)) {
          CustomReuseStrategy.delete = null
          return;
      }
      CustomReuseStrategy.handlers[this.getRouteUrl(route)] = handle;
  }

  //ATTACHED ROUTE IF ALREADY NOT PRESENT
  public shouldAttach(route: ActivatedRouteSnapshot): boolean {
      return !!CustomReuseStrategy.handlers[this.getRouteUrl(route)];
  }

  //THIS METHOD IS USED FOR RETRIEVING ROUTE STATE
  public retrieve(route: ActivatedRouteSnapshot): DetachedRouteHandle {
      if (!route.routeConfig) {
          return null
      }
      return CustomReuseStrategy.handlers[this.getRouteUrl(route)];
  }

  //THIS METHOD RUN WHEN USER CHANGE ROUTE EVEY TIME AND CHECK CURRENT ROUTE WANT TO USED CUSTOM STRATEGY OR NOT
  public shouldReuseRoute(future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot): boolean {
      return future.routeConfig === curr.routeConfig &&
          JSON.stringify(future.params) === JSON.stringify(curr.params);
  }

  //FIND OUT ACTUAL ROUTE NAME AND ROUTE THE URL
  private getRouteUrl(route: ActivatedRouteSnapshot) {
      return route['_routerState'].url.replace(/\//g, '_')
  }
}

Here is my working example for routes with children and parameters:

import {ActivatedRouteSnapshot, DetachedRouteHandle, RouteReuseStrategy} from '@angular/router';

export class CustomReuseStrategy implements RouteReuseStrategy {

handlers: { [key: string]: DetachedRouteHandle } = {};

shouldDetach(route: ActivatedRouteSnapshot): boolean {
    return route.data.shouldReuse || false;
}

store(route: ActivatedRouteSnapshot, handle: {}): void {
    if (route.data.shouldReuse && this.getUrl(route)) {
        this.handlers[this.getUrl(route)] = handle;
    }
}

shouldAttach(route: ActivatedRouteSnapshot): boolean {
    return !!this.handlers[this.getUrl(route)];
}

retrieve(route: ActivatedRouteSnapshot): any {
    if (!this.getUrl(route)) {
        return null;
    }
    return this.handlers[this.getUrl(route)];
}

shouldReuseRoute(future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot): boolean {
    return future.routeConfig === curr.routeConfig && JSON.stringify(future.params) === JSON.stringify(curr.params);
}

getUrl(route: ActivatedRouteSnapshot) {
    if (!route.parent.url.join('/') || !route.url.join('/')) {
        return null;
    }
    let url = '';
    if (route.parent.url.join('/')) {
        url += route.parent.url.join('/') + '/';
    }
    if (route.url.join('/')) {
        url += route.url.join('/');
    }
    return url === '' ? null : url;
}
}

And inside routing config:

export const myRoute: Route = {

    path: 'my',
    component: MyComponent,
    data: {
        pageTitle: 'MY'
    },
    children: [
        {
            path: '',
            redirectTo: 'dashboard',
            pathMatch: 'full'
        },
        {
            path: 'dashboard',
            component: MyDashboardComponent,
            data: {
                shouldReuse: true
            }
        },
        {
            path: 'orders',
            component: MyOrdersComponent,
            data: {
                shouldReuse: true
            }
        },
        {
            path: 'event/:id',
            component: MyEventComponent,
            data: {
                shouldReuse: true
            }
        }
    ]
};
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!