angular Routing Multiplexing Strategy

Recently, when working out the refresh function of single page components, I came into contact with the routing reuse strategy, and summarized the following:
Usage:

  • New routing multiplexing file SimpleReuse Strategy.ts:
import { RouteReuseStrategy, DefaultUrlSerializer, ActivatedRouteSnapshot, DetachedRouteHandle } from '@angular/router';
// import { compact } from 'rxjs';
import { ComponentRef } from '@angular/core';

export class SimpleReuseStrategy implements RouteReuseStrategy {

  public static handlers: { [key: string]: DetachedRouteHandle } = {};

  private static getRouteUrl(route: ActivatedRouteSnapshot) {
    return route['_routerState'].url.replace(/[\/, -]/g, '_');
  }

  /** Represents that multiplexing is allowed for all routes. If you have routes that you don't want to use, you can add some business logic here. */
  public shouldDetach(route: ActivatedRouteSnapshot): boolean {
    return !(!route.routeConfig || route.routeConfig.loadChildren);
  }

  /** Triggered when the route leaves. Store route snapshots by path as key & component current instance object */
  public store(route: ActivatedRouteSnapshot, handle: DetachedRouteHandle): void {
    SimpleReuseStrategy.handlers[SimpleReuseStrategy.getRouteUrl(route)] = handle;
  }

  /** If path is considered to be allowed to restore routing in the cache */
  public shouldAttach(route: ActivatedRouteSnapshot): boolean {
    return !!route.routeConfig && !!SimpleReuseStrategy.handlers[SimpleReuseStrategy.getRouteUrl(route)];
  }

  /** Get a snapshot from the cache and return nul if not */
  public retrieve(route: ActivatedRouteSnapshot): DetachedRouteHandle {
    if (!route.routeConfig || route.routeConfig.loadChildren) {
      return null;
    }
    // console.log(SimpleReuseStrategy.handlers);
    return SimpleReuseStrategy.handlers[SimpleReuseStrategy.getRouteUrl(route)];
  }

  /** Enter the routing trigger to determine whether the same route is available */
  public shouldReuseRoute(future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot): boolean {
    return future.routeConfig === curr.routeConfig;
  }

  /** Clear cache */
  public clearCacheHandle(){
    for (const key in SimpleReuseStrategy.handlers) {
      if (SimpleReuseStrategy.handlers[key]){
        this.deactivateOutlet(SimpleReuseStrategy.handlers[key])
      }
    }
  }

  /** Handling the problem of different links to the same component */
  private deactivateOutlet(handle: DetachedRouteHandle): void {
    const componentRef: ComponentRef<any> = handle ? handle['componentRef'] : null;
    if (componentRef) {
      componentRef.destroy();
    }
  }

  public clearCacheByUrl(url: string){
    const handleUrl = url.replace(/[\/, -]/g, '_');
    for (const key in SimpleReuseStrategy.handlers) {
      if (key === handleUrl){
        delete SimpleReuseStrategy.handlers[key];
      }
    }
  }

}

  • Introduce this file in AppModule:
@NgModule({
  declarations: [AppComponent],
  imports: [
    BrowserModule,
    BrowserAnimationsModule,
    HttpClientModule,
    DelonModule.forRoot(),
    CoreModule,
    SharedModule,
    LayoutModule,
    RoutesModule,
    ...I18NSERVICE_MODULES,
    ...GLOBAL_THIRD_MODULES,
    ...FORM_MODULES,
    // ...MOCKMODULE,
    // TreeviewModule.forRoot(),
  ],
  providers: [...LANG_PROVIDES, ...INTERCEPTOR_PROVIDES, ...I18NSERVICE_PROVIDES, ...APPINIT_PROVIDES, ApiService, LogService,
    // { provide: RouteReuseStrategy, useClass: ReuseTabStrategy, deps: [ ReuseTabService] },
    { provide: RouteReuseStrategy, useClass: SimpleReuseStrategy },
  ],
  bootstrap: [AppComponent],
})
export class AppModule {}

Now that the reuse strategy has come into effect, here are the main problems encountered in the configuration process:
1,Cannot reattach ActivatedRouteSnapshot created from a different route
Solution:
Replace shouldDetach and retrieve methods as follows (must be replaced at the same time):

/** Represents that multiplexing is allowed for all routes. If you have routes that you don't want to use, you can add some business logic here. */
  public shouldDetach(route: ActivatedRouteSnapshot): boolean {
    if (!route.routeConfig || route.routeConfig.loadChildren) {
      return false;
    }
    return true;
  }
/** Get a snapshot from the cache and return nul if not */
  public retrieve(route: ActivatedRouteSnapshot): DetachedRouteHandle {
    if (!route.routeConfig) {
      return null;
    }
    if(route.routeConfig.loadChildren) return null;
    return SimpleReuseStrategy.handlers[SimpleReuseStrategy.getRouteUrl(route)];
  }

2. The store method in the routing multiplexing strategy can only trigger the route jump caused by the following two ways:
(1):
(2): Route jumps initiated by router classes, such as router.navigate() or router.navigateByUrl, etc.
If it is initiated by direct instruction, the store method is not triggered, such as < app-dashboard * ngIf= "show">

Tags: angular snapshot

Posted on Tue, 08 Oct 2019 17:49:52 -0700 by fuii_koh