]>
Commit | Line | Data |
---|---|---|
489290b8 C |
1 | import { ActivatedRouteSnapshot, DetachedRouteHandle, RouteReuseStrategy } from '@angular/router' |
2 | ||
3 | export class CustomReuseStrategy implements RouteReuseStrategy { | |
4 | storedRouteHandles = new Map<string, DetachedRouteHandle>() | |
5 | recentlyUsed: string | |
6 | ||
7 | private readonly MAX_SIZE = 2 | |
8 | ||
9 | // Decides if the route should be stored | |
10 | shouldDetach (route: ActivatedRouteSnapshot): boolean { | |
11 | return this.isReuseEnabled(route) | |
12 | } | |
13 | ||
14 | // Store the information for the route we're destructing | |
15 | store (route: ActivatedRouteSnapshot, handle: DetachedRouteHandle): void { | |
16 | if (!handle) return | |
17 | ||
18 | const key = this.generateKey(route) | |
19 | this.recentlyUsed = key | |
20 | ||
21 | console.log('Storing component %s to reuse later.', key); | |
22 | ||
23 | (handle as any).componentRef.instance.disableForReuse() | |
24 | ||
25 | this.storedRouteHandles.set(key, handle) | |
26 | ||
27 | this.gb() | |
28 | } | |
29 | ||
30 | // Return true if we have a stored route object for the next route | |
31 | shouldAttach (route: ActivatedRouteSnapshot): boolean { | |
32 | const key = this.generateKey(route) | |
33 | return this.isReuseEnabled(route) && this.storedRouteHandles.has(key) | |
34 | } | |
35 | ||
36 | // If we returned true in shouldAttach(), now return the actual route data for restoration | |
37 | retrieve (route: ActivatedRouteSnapshot): DetachedRouteHandle { | |
38 | if (!this.isReuseEnabled(route)) return undefined | |
39 | ||
40 | const key = this.generateKey(route) | |
41 | this.recentlyUsed = key | |
42 | ||
43 | console.log('Reusing component %s.', key) | |
44 | ||
45 | const handle = this.storedRouteHandles.get(key) | |
46 | if (!handle) return handle; | |
47 | ||
48 | (handle as any).componentRef.instance.enabledForReuse() | |
49 | ||
50 | return handle | |
51 | } | |
52 | ||
53 | // Reuse the route if we're going to and from the same route | |
54 | shouldReuseRoute (future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot): boolean { | |
55 | return future.routeConfig === curr.routeConfig | |
56 | } | |
57 | ||
58 | private gb () { | |
59 | if (this.storedRouteHandles.size >= this.MAX_SIZE) { | |
60 | this.storedRouteHandles.forEach((r, key) => { | |
61 | if (key === this.recentlyUsed) return | |
62 | ||
63 | console.log('Removing stored component %s.', key); | |
64 | ||
65 | (r as any).componentRef.destroy() | |
66 | this.storedRouteHandles.delete(key) | |
67 | }) | |
68 | } | |
69 | } | |
70 | ||
71 | private generateKey (route: ActivatedRouteSnapshot) { | |
72 | const reuse = route.data.reuse | |
73 | if (!reuse) return undefined | |
74 | ||
75 | return reuse.key + JSON.stringify(route.queryParams) | |
76 | } | |
77 | ||
78 | private isReuseEnabled (route: ActivatedRouteSnapshot) { | |
79 | return route.data.reuse && route.data.reuse.enabled && route.queryParams['a-state'] | |
80 | } | |
81 | } |