Angular路由缓存

222 阅读1分钟

路由缓存服务

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

export class ReuseStrategy implements RouteReuseStrategy {
  cacheRouters = new Map<string, DetachedRouteHandle>();

  public clearCachedRoute(key: string) {
    const handle = this.cacheRouters.get(key);

    if (handle) {
      (handle as any).componentRef.destroy();
    }

    this.cacheRouters.delete(key);
  }

  public clearCacheOnNewUrl(url: string) {
    this.cacheRouters.forEach((val, key) => {
      if (url.indexOf(key) === -1) {
        this.clearCachedRoute(key);
      }
    });
  }

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

  retrieve(route: ActivatedRouteSnapshot): DetachedRouteHandle {
    const url = this.getFullRouteURL(route);
    if (route.data.keep && this.cacheRouters.has(url)) {
      return this.cacheRouters.get(url);
    } else {
      return null;
    }
  }

  shouldDetach(route: ActivatedRouteSnapshot): boolean {
    return Boolean(route.data.keep);
  }
 
  store(route: ActivatedRouteSnapshot, handle: DetachedRouteHandle): void {
    const url = this.getFullRouteURL(route);
    this.cacheRouters.set(url, handle);
  }

  shouldAttach(route: ActivatedRouteSnapshot): boolean {
    const url = this.getFullRouteURL(route);
    return Boolean(route.data.keep) && this.cacheRouters.has(url);
  }

  private getFullRouteURL(route: ActivatedRouteSnapshot): string {
    const { pathFromRoot } = route;
    let fullRouteUrlPath: string[] = [];
    pathFromRoot.forEach((item: ActivatedRouteSnapshot) => {
      fullRouteUrlPath = fullRouteUrlPath.concat(this.getRouteUrlPath(item));
    });
    return `/${fullRouteUrlPath.join("/")}`;
  }
  private getRouteUrlPath(route: ActivatedRouteSnapshot) {
    return route.url.map((urlSegment) => urlSegment.path);
  }
}

路由配置keep flag

import { NgModule } from '@angular/core';
import { RouterModule, Routes } from '@angular/router';
import { RicmQuestionnaireComponent } from './ricm-questionnaire.component';

const routes: Routes = [
  {
    path: '',
    component: RicmQuestionnaireComponent,
    data: { keep: true } // 缓存服务中将使用到这个flag来判断哪些路由需要被缓存
  }
];

@NgModule({
  imports: [RouterModule.forChild(routes)],
  exports: [RouterModule]
})
export class RicmQuestionnaireRoutingModule { }

在app.module.ts中注入缓存服务

@NgModule({
  declarations: [
    AppComponent
  ],
  imports: [
    BrowserAnimationsModule,
    AppRoutingModule,
    BrowserModule,
    CoreModule
  ],
  providers: [
    { provide: RouteReuseStrategy, useClass: ReuseStrategy } // 注入缓存服务
  ],
  bootstrap: [AppComponent],
  schemas: [
    NO_ERRORS_SCHEMA
  ]
})
export class AppModule { }