Thodoris
Thodoris

Reputation: 742

How to activate RouteReuseStrategy only for specific routes

Is there a way to implement RouteReuseStrategy only for specific routes?

Meaning each route with children, getting its own custom implementation of RouteReuseStrategy, and whose methods only fire when a route in a specific 'tree' is activated.

I currently use the code from this answer, but I want to expand it with the above logic if possible.

Upvotes: 16

Views: 19296

Answers (3)

Dadv
Dadv

Reputation: 413

The accepted answer is a great solution, but it's not realy adapted to children routes because route.routeConfig.path will refer to the last children route name.

So for avoid this pb I use a named cache route :

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

export class ListReuseStrategy implements RouteReuseStrategy {

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

  shouldDetach(route: ActivatedRouteSnapshot): boolean {    
    return !!route.data["cacheRouteAs"] || false;
  }

  store(route: ActivatedRouteSnapshot, handle: DetachedRouteHandle): void {
    if (!!route.data["cacheRouteAs"]) {
      this.handlers[route.data["cacheRouteAs"]] = handle;
    }
  }

  shouldAttach(route: ActivatedRouteSnapshot): boolean {
    return !!route.data["cacheRouteAs"] && !!this.handlers[route.data["cacheRouteAs"]];
  }

  retrieve(route: ActivatedRouteSnapshot) {
    if (!route.routeConfig || !route.routeConfig.path || !route.data["cacheRouteAs"]) 
        return null;

    return this.handlers[route.data["cacheRouteAs"]];
  }

  shouldReuseRoute(future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot): boolean {
    return !!future.data["cacheRouteAs"] || false;
  }

}

then in route I use :

 data:{cacheRouteAs : "uniqueNameOfMyCachePage" }

Upvotes: 1

Ploppy
Ploppy

Reputation: 15353

Create a custom route reuse strategy

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

export class CustomRouteReuseStrategy implements RouteReuseStrategy {

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

  shouldDetach(route: ActivatedRouteSnapshot): boolean {
    return route.data.shouldReuse || false;
  }

  store(route: ActivatedRouteSnapshot, handle: {}): void {
    if (route.data.shouldReuse) {
      this.handlers[route.routeConfig.path] = handle;
    }
  }

  shouldAttach(route: ActivatedRouteSnapshot): boolean {
    return !!route.routeConfig && !!this.handlers[route.routeConfig.path];
  }

  retrieve(route: ActivatedRouteSnapshot): {} {
    if (!route.routeConfig) return null;
    return this.handlers[route.routeConfig.path];
  }

  shouldReuseRoute(future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot): boolean {
    return future.data.shouldReuse || false;
  }

}

In your router module, implement the new strategy in the providers array:

providers: [
  { provide: RouteReuseStrategy, useClass: CustomRouteReuseStategy },
  ...
]

Then, declare the desired route with a data property 'shouldReuse' set to true

{ path: 'myPath', component: MyComponent, data: { shouldReuse: true } },

Only the routes with the data property shouldReuse set to true will be reused.

Upvotes: 39

Jmsdb
Jmsdb

Reputation: 535

Yes, you can do this by writing your own RouteReuseStrategy (CustomReuseStrategy).

To black or white list routes, you can search for a data property which you can set in the router-module under the route and then choose to attach the component (to reuse it later), or not.

Helpful links to get you started:

Upvotes: 0

Related Questions