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
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;
}
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.
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;
}
}
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;
}
}
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;
}
}