Using the Angular RouteReuseStrategy caching (routing) component

Using the Angular RouteReuseStrategy cache component

Cache components with Angular RouteReuseStrategy

RouteReuseStrategy provider allows us to control the behavior of Angular routing and component lifecycle.

When we switch between components, Angular will destroy the previous component and create a new one. In most cases, we may not want to let it work like this, because each time a component is loaded, there may be many expensive operations like HTTP requests.

At this time, route reuse strategy is needed.

What is route reuse strategy

The RouteReuseStrategy interface declares five methods.

shouldReuseRoute

This method is called every time the route is switched. The future parameter is the route to leave, and the curr parameter is the route to load. If this method returns true, the route will not jump (meaning the route has not changed). If it returns false, the route changes and the rest of the methods are called.

shouldReuseRoute(future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot): boolean {
    // Default behavior
    return future.routeConfig === curr.routeConfig;
}

shouldAttach

The route has just been opened. When we load it on the component of the route, shouldAttach will be called. This method will be called once the component is loaded. If this method returns true, the retrieve method will be called. Otherwise, the component will be recreated.

shouldAttach(route: ActivatedRouteSnapshot): boolean;

retrieve

This method is called when the shouldatach method returns true. Provides the parameters of the current route (the route just opened), and returns a cached RouteHandle. If null is returned, there is no effect. We can use this method to get any cached RouteHandle manually. The framework doesn't manage it automatically. We need to implement it manually.

retrieve(route: ActivatedRouteSnapshot): DetachedRouteHandle | null;

shouldDetach

This method is called when leaving the current route. If true is returned, the store method is called.

shouldDetach(route: ActivatedRouteSnapshot): boolean;

store

This method is called when and only if the shouldDetach method returns true. We can implement how to cache RouteHandle here. The contents cached in this method will be used in the retrieve method. It provides the route we left and the RouteHandle.

store(route: ActivatedRouteSnapshot, detachedTree: DetachedRouteHandle): void;

Example

src/services/route-strategy.service.ts:

import { RouteReuseStrategy, DetachedRouteHandle, ActivatedRouteSnapshot } from '@angular/router';
export class RouteStrategyService implements RouteReuseStrategy {
  public static handlers: { [key: string]: DetachedRouteHandle } = {};
  public static deleteRouteSnapshot(path: string): void {
    const name = path.replace(/\//g, '_');
    if (RouteStrategyService.handlers[name]) {
      delete RouteStrategyService.handlers[name];
    }
  }
  /**
   * Determine whether the current route needs to be cached
   * When this method returns false, the route changes and the rest of the methods are called
   * @param {ActivatedRouteSnapshot} future
   * @param {ActivatedRouteSnapshot} curr
   * @returns {boolean}
   * @memberof CacheRouteReuseStrategy
   */
  public shouldReuseRoute(future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot): boolean {
    return future.routeConfig === curr.routeConfig
      && JSON.stringify(future.params) === JSON.stringify(curr.params);
  }
  /**
   * This method is called when leaving the current route
   * If you return true, the store method will be called
   * @param {ActivatedRouteSnapshot} route
   * @returns {boolean}
   * @memberof CacheRouteReuseStrategy
   */
  public shouldDetach(route: ActivatedRouteSnapshot): boolean {
    return true;
  }
  /**
   * Write route to cache
   * How to cache RouteHandle
   * Provides the route we left and RouteHandle
   * @param {ActivatedRouteSnapshot} route
   * @param {DetachedRouteHandle} detachedTree
   * @memberof CacheRouteReuseStrategy
   */
  public store(route: ActivatedRouteSnapshot, detachedTree: DetachedRouteHandle): void {
    RouteStrategyService.handlers[this.getPath(route)] = detachedTree;
  }
  /**
   * Route is navigated. If this method returns true, the retrieve method will be triggered
   * If you return false, this component will be recreated
   * @param {ActivatedRouteSnapshot} route
   * @returns {boolean}
   * @memberof CacheRouteReuseStrategy
   */
  public shouldAttach(route: ActivatedRouteSnapshot): boolean {
    return !!RouteStrategyService.handlers[this.getPath(route)];
  }
  /**
   * Read cached route from cache
   * Provides the parameters of the current route (the route just opened), and returns a cached RouteHandle
   * You can use this method to manually get any cached RouteHandle
   * @param {ActivatedRouteSnapshot} route
   * @returns {(DetachedRouteHandle | null)}
   * @memberof CacheRouteReuseStrategy
   */
  public retrieve(route: ActivatedRouteSnapshot): DetachedRouteHandle | null {
    return RouteStrategyService.handlers[this.getPath(route)] || null;
  }
  private getPath(route: ActivatedRouteSnapshot): string {
    // tslint:disable-next-line: no-string-literal
    const path = route['_routerState'].url.replace(/\//g, '_');
    return path;
  }
}

src/app/app.module.ts:

import { RouteReuseStrategy } from '@angular/router';
import { RouteStrategyService } from '../services/route-strategy.service';

@NgModule({
    ...
    providers: [
        ...
        { provide: RouteReuseStrategy, useClass: RouteStrategyService }
    ],
    bootstrap: [AppComponent]
})
export class AppModule { }

The above example runs with all routing components cached.
For example, when implementing the tab effect, close the tab and call the deleteRouteSnapshot method in RouteStrategyService to delete the cached page.

There may be a problem here. If you don't want to use this route cache, please delete the providers in app.module.ts instead of returning the shouldReuseRoute of RouteStrategyService to true all the time. This will cause the problem that the route jump page doesn't jump. The reason is unknown temporarily.

The following is the operation rendering:

The end...
Last updated by Jehorn, 11/1/2019

Tags: Javascript angular REST JSON

Posted on Sun, 03 Nov 2019 03:04:20 -0800 by Jin597