浅记一下angular使用RouteReuseStrategy实现keep-alive功能(自用)

1,453 阅读1分钟

1.新建一个类 simpleReuseStrategy.ts

import { Injectable } from '@angular/core';

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

@Injectable()

export class SimpleReuseStrategy implements RouteReuseStrategy {

  private static _routeCache = new Map<string, DetachedRouteHandle>();

  private static _waitDelete: string; // 待删除的快照


  // 用于删除路由快照

  public static deleteRouteSnapshot(url: string): void {

    if (url[0] === '/') {

      url = url.substring(1);

    }

    url = url.replace(/\//g, '_');

    if (SimpleReuseStrategy._routeCache.has(url)) {

      SimpleReuseStrategy._routeCache.delete(url);

    }

    SimpleReuseStrategy._waitDelete = url;

  }


  // 进入路由触发,判断是否是同一路由

  public shouldReuseRoute(future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot): boolean {

    return future.routeConfig === curr.routeConfig && JSON.stringify(future.params) === JSON.stringify(curr.params);

  }


  // 表示对所有路由允许复用 如果有路由不想利用可以在这加一些业务逻辑判断,这里判断路由是否有keepAlive数据判断是否复用

  public shouldDetach(route: ActivatedRouteSnapshot): boolean {

    return route.data.keepAlive;

  }


  // 当路由离开时会触发, 按path作为key存储路由快照&组件当前实例对象

  // 如果路由配置为‘’,则出现Cannot reattach ActivatedRouteSnapshot created from a different route问题

  public store(route: ActivatedRouteSnapshot, handle: DetachedRouteHandle): void {

    const url = this._getFullRouteUrl(route);

    if (SimpleReuseStrategy._waitDelete && SimpleReuseStrategy._waitDelete === url) {

      // 如果待删除是当前路由,且未存储过则不存储快照

      SimpleReuseStrategy._waitDelete = null;

      return;

    }

    SimpleReuseStrategy._routeCache.set(url, handle);

  }


  // 若 url 在缓存中有的都认为允许还原路由

  public shouldAttach(route: ActivatedRouteSnapshot): boolean {

    const url = this._getFullRouteUrl(route);

    // window.console.log('是否允许还原路由:', SimpleReuseStrategy._routeCache.has(url));

    return SimpleReuseStrategy._routeCache.has(url);

  }



  // 从缓存中获取快照,若无则返回nul

  public retrieve(route: ActivatedRouteSnapshot): DetachedRouteHandle {

    const url = this._getFullRouteUrl(route);

    return SimpleReuseStrategy._routeCache.has(url) ? SimpleReuseStrategy._routeCache.get(url) : null;

  }


  // 获取完整路由

  private _getFullRouteUrl(route: ActivatedRouteSnapshot): string {

    return this._getFullRouteUrlPaths(route)

        .filter(Boolean)

        .join('/')

        .replace(/\//g, '_');

  }


  private _getFullRouteUrlPaths(route: ActivatedRouteSnapshot): string[] {

    const paths = route.url.map((urlSegment) => urlSegment.path);

    return route.parent ? [...this._getFullRouteUrlPaths(route.parent), ...paths] : paths;

  }

}

2.在providers里注入

providers: [
    { provide: RouteReuseStrategy, useClass: SimpleReuseStrategy }
],

3.在路由上新增keepAlive属性

{
   path: 'message-center-list',
   canLoad: [AuthGuard, AclGuard],
   loadChildren: () => import('./pages/message-center-list/message-center-list.module')
        .then((m) => m.MessageCenterListModule),
   data: {
       keepAlive: true,
   }
},