1. 路由复用策略服务 route-reuse.service.ts
ts 107行
import { RouteReuseStrategy, DetachedRouteHandle, ActivatedRouteSnapshot } from '@angular/router';
import { ComponentRef, Injectable } from '@angular/core';
@Injectable()
export class RouteReuseService implements RouteReuseStrategy {
private handlers: { [key: string]: RootHandler } = {};
shouldDetach(route: ActivatedRouteSnapshot): boolean {
return this.isDetachable(route);
}
store(route: ActivatedRouteSnapshot, handler: DetachedRouteHandle) {
const storeKey = this.getStoreKey(route);
if (handler) {
const rootHandler = {
handle: handler,
storeTime: +new Date()
};
this.handlers[storeKey] = rootHandler;
}
}
shouldAttach(route: ActivatedRouteSnapshot): boolean {
const storeKey = this.getStoreKey(route);
if (this.isAtachable(route, storeKey)) {
this.clearNewerHandlerOnAttach(this.handlers[storeKey].storeTime);
return true;
}
return false;
}
retrieve(route: ActivatedRouteSnapshot): DetachedRouteHandle {
const storeKey = this.getStoreKey(route);
return this.handlers[storeKey]?.handle;
}
shouldReuseRoute( future: ActivatedRouteSnapshot, current: ActivatedRouteSnapshot): boolean {
return future.routeConfig === current.routeConfig;
}
private getResolvedUrl(route: ActivatedRouteSnapshot): string {
return route.pathFromRoot
.map(v => v.url.map(segment => segment.toString()).join('/'))
.join('/');
}
private getStoreKey(route: ActivatedRouteSnapshot): string {
const baseUrl = this.getResolvedUrl(route);
const childrenParts = [];
let deepestChild = route;
while (deepestChild.firstChild) {
deepestChild = deepestChild.firstChild;
childrenParts.push(deepestChild.url.join('/'));
}
return baseUrl + '////' + childrenParts.join('/');
}
private isDetachable(route: ActivatedRouteSnapshot) {
if ( route?.routeConfig?.data?.keep) {
return true;
}
return false;
}
private isAtachable(route: ActivatedRouteSnapshot, storeKey: string) {
if (this.isDetachable(route) && this.handlers[storeKey]?.handle) {
return true;
}
return false;
}
private clearNewerHandlerOnAttach(storeTime: number) {
const handlerKeys = Object.keys(this.handlers);
handlerKeys.forEach(k => {
if (this.handlers[k].storeTime > storeTime) {
const componentRef: ComponentRef<any> = (this.handlers[k].handle as any).componentRef;
if (componentRef) {
componentRef.destroy();
}
delete this.handlers[k];
}
});
}
}
export interface RootHandler {
handle: DetachedRouteHandle;
storeTime: number;
}
2. 使用在路由模块中 app-routing.module.ts
...
import { RouteReuseStrategy, RouterModule, Routes } from '@angular/router';
import { RouteReuseService } from './route-reuse.service';
...
const routes: Routes = [
...
{
path: 'index',
data: {keep: true},
component: IndexComponent
},
...
];
...
@NgModule({
...
providers: [
{ provide: RouteReuseStrategy, useClass: RouteReuseService }
]
})
2022-02-22 03:14