1 import { ActivatedRouteSnapshot, DetachedRouteHandle, RouteReuseStrategy } from '@angular/router'
2 import { Injectable } from '@angular/core'
5 export class CustomReuseStrategy implements RouteReuseStrategy {
6 storedRouteHandles = new Map<string, DetachedRouteHandle>()
9 private readonly MAX_SIZE = 2
11 // Decides if the route should be stored
12 shouldDetach (route: ActivatedRouteSnapshot): boolean {
13 return this.isReuseEnabled(route)
16 // Store the information for the route we're destructing
17 store (route: ActivatedRouteSnapshot, handle: DetachedRouteHandle): void {
20 const key = this.generateKey(route)
21 this.recentlyUsed = key
23 console.log('Storing component %s to reuse later.', key);
25 (handle as any).componentRef.instance.disableForReuse()
27 this.storedRouteHandles.set(key, handle)
32 // Return true if we have a stored route object for the next route
33 shouldAttach (route: ActivatedRouteSnapshot): boolean {
34 const key = this.generateKey(route)
35 return this.isReuseEnabled(route) && this.storedRouteHandles.has(key)
38 // If we returned true in shouldAttach(), now return the actual route data for restoration
39 retrieve (route: ActivatedRouteSnapshot): DetachedRouteHandle {
40 if (!this.isReuseEnabled(route)) return undefined
42 const key = this.generateKey(route)
43 this.recentlyUsed = key
45 console.log('Reusing component %s.', key)
47 const handle = this.storedRouteHandles.get(key)
48 if (!handle) return handle;
50 (handle as any).componentRef.instance.enabledForReuse()
55 // Reuse the route if we're going to and from the same route
56 shouldReuseRoute (future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot): boolean {
57 return future.routeConfig === curr.routeConfig
61 if (this.storedRouteHandles.size >= this.MAX_SIZE) {
62 this.storedRouteHandles.forEach((r, key) => {
63 if (key === this.recentlyUsed) return
65 console.log('Removing stored component %s.', key);
67 (r as any).componentRef.destroy()
68 this.storedRouteHandles.delete(key)
73 private generateKey (route: ActivatedRouteSnapshot) {
74 const reuse = route.data.reuse
75 if (!reuse) return undefined
77 return reuse.key + JSON.stringify(route.queryParams)
80 private isReuseEnabled (route: ActivatedRouteSnapshot) {
81 return route.data.reuse && route.data.reuse.enabled && route.queryParams[ 'a-state' ]