Angular2 doesn't work Custom Reuse Strategy with Lazy module loading

前端 未结 5 1140
花落未央
花落未央 2020-12-08 16:52

I tried to use custom reuse strategy in my angular2 project, but I found it doesn\'t work with lazy module loading. Anyone who know about this? My project i

相关标签:
5条回答
  • 2020-12-08 17:13

    To make it work you should take into account the full path instead of simple route.routeConfig.path as most articles suggests. For example:

    private getKey(route: ActivatedRouteSnapshot): string {
        return route.pathFromRoot
            .map((el: ActivatedRouteSnapshot) => el.routeConfig ? el.routeConfig.path : '')
            .filter(str => str.length > 0)
            .join('');
    }
    
    store(route: ActivatedRouteSnapshot, handle: DetachedRouteHandle): void {
        this.handlers[this.getKey(route)] = handle;
    }
    
    0 讨论(0)
  • 2020-12-08 17:26

    RouteReuseStrategy does work with LazyLoaded components.

    The problem here is that you're using route.routeConfig.path as the key to store and retrieve the Handles.

    I don't know why, but with LazyLoaded modules, route.routeConfig.path is empty when executing shouldAttach

    The solution I use is to define a custom key in my routes, like:

    { path: '...', loadChildren: '...module#...Module', data: { key: 'custom_key' } }
    

    This key value can be easily accessed in the ActivatedRouteSnapshot, like:

    route.data.key
    

    With this key you can store and retrieve the handles correctly.

    0 讨论(0)
  • 2020-12-08 17:27

    Use this one. It use component name as the key to store and retrieve the Handles.

    import {ActivatedRouteSnapshot, DetachedRouteHandle, RouteReuseStrategy} from '@angular/router';
    
    export class CustomReuseStrategy implements RouteReuseStrategy {
    
    
      handlers: { [key: string]: DetachedRouteHandle } = {};
    
    
      shouldDetach(route: ActivatedRouteSnapshot): boolean {
        return true;
      }
    
      store(route: ActivatedRouteSnapshot, handle: DetachedRouteHandle): void {
        this.handlers[this.getKey(route)] = handle;
      }
    
      shouldAttach(route: ActivatedRouteSnapshot): boolean {
        return !!route.routeConfig && !!this.handlers[this.getKey(route)];
      }
    
      retrieve(route: ActivatedRouteSnapshot): DetachedRouteHandle {
        if (!route.routeConfig) {
          return null;
        }
        return this.handlers[this.getKey(route)];
      }
    
      shouldReuseRoute(future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot): boolean {
        return curr.routeConfig === future.routeConfig;
      }
    
      private getKey(route: ActivatedRouteSnapshot) {
        let key: string;
        if (route.component) {
          key = route.component['name'];
        } else {
          key = route.firstChild.component['name'];
        }
        return key;
      }
    
    }
    
    0 讨论(0)
  • 2020-12-08 17:37

    use this ReuseStrategy

    import { ActivatedRouteSnapshot, DetachedRouteHandle, RouteReuseStrategy } from '@angular/router';
    export class CustomReuseStrategy implements RouteReuseStrategy {
    
      private handlers: {[key: string]: DetachedRouteHandle} = {};
    
    
      constructor() {
    
      }
    
      shouldDetach(route: ActivatedRouteSnapshot): boolean {
        return true;
      }
    
      store(route: ActivatedRouteSnapshot, handle: DetachedRouteHandle): void {
        this.handlers[route.url.join("/") || route.parent.url.join("/")] = handle;
      }
    
      shouldAttach(route: ActivatedRouteSnapshot): boolean {
        return !!this.handlers[route.url.join("/") || route.parent.url.join("/")];
      }
    
      retrieve(route: ActivatedRouteSnapshot): DetachedRouteHandle {
        return this.handlers[route.url.join("/") || route.parent.url.join("/")];
      }
    
      shouldReuseRoute(future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot): boolean {
        return future.routeConfig === curr.routeConfig;
      }
    
    }
    
    0 讨论(0)
  • 2020-12-08 17:38

    use this custom Reuse Strategy file for lazy module loading

    import { ActivatedRouteSnapshot, RouteReuseStrategy, DetachedRouteHandle } from '@angular/router';
    
    /** Interface for object which can store both:
     * An ActivatedRouteSnapshot, which is useful for determining whether or not you should attach a route (see this.shouldAttach)
     * A DetachedRouteHandle, which is offered up by this.retrieve, in the case that you do want to attach the stored route
     */
    interface RouteStorageObject {
        snapshot: ActivatedRouteSnapshot;
        handle: DetachedRouteHandle;
    }
    
    export class CustomReuseStrategy implements RouteReuseStrategy {
    
        handlers: {[key: string]: DetachedRouteHandle} = {};
    
        shouldDetach(route: ActivatedRouteSnapshot): boolean {
            console.debug('CustomReuseStrategy:shouldDetach', route);
            return !!route.data && !!(route.data as any).shouldDetach;
        }
    
        store(route: ActivatedRouteSnapshot, handle: DetachedRouteHandle): void {
            console.debug('CustomReuseStrategy:store', route, handle);
            this.handlers[route.data['key']]= handle;
        }
    
        shouldAttach(route: ActivatedRouteSnapshot): boolean {
            console.debug('CustomReuseStrategy:shouldAttach', route);
            return !!route.data && !!this.handlers[route.data['key']];
        }
    
        retrieve(route: ActivatedRouteSnapshot): DetachedRouteHandle {
            console.debug('CustomReuseStrategy:retrieve', route);
            if (!route.data) return null;
            return this.handlers[route.data['key']];
        }
    
        shouldReuseRoute(future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot): boolean {
            console.debug('CustomReuseStrategy:shouldReuseRoute', future, curr);
            return future.data === curr.data;
        }
    
    }
    
    0 讨论(0)
提交回复
热议问题