|
@@ -1,58 +1,131 @@
|
1
|
|
-import {RouteReuseStrategy, DefaultUrlSerializer, ActivatedRouteSnapshot, DetachedRouteHandle} from '@angular/router';
|
|
1
|
+import { RouteReuseStrategy, DefaultUrlSerializer, ActivatedRouteSnapshot, DetachedRouteHandle } from '@angular/router';
|
2
|
2
|
|
|
3
|
+type SimpleDetachedRouteHandle = DetachedRouteHandle | null;
|
3
|
4
|
/**
|
4
|
5
|
* 路由复用策略
|
5
|
6
|
*/
|
6
|
7
|
export class SimpleReuseStrategy implements RouteReuseStrategy {
|
7
|
8
|
|
8
|
|
- public static handlers: { [key: string]: DetachedRouteHandle } = {};
|
9
|
|
- private static waitDelete: string;
|
|
9
|
+ private static routeCache = new Map<string, DetachedRouteHandle>();
|
|
10
|
+ private static waitDelete: string | null;
|
10
|
11
|
|
11
|
|
- /** 表示对所有路由允许复用 如果你有路由不想利用可以在这加一些业务逻辑判断 */
|
|
12
|
+ /**
|
|
13
|
+ * 用于删除路由快照
|
|
14
|
+ *
|
|
15
|
+ * @param {string} url - 需要删除路由的 URL。
|
|
16
|
+ * @return {void}
|
|
17
|
+ */
|
|
18
|
+ public static deleteRouteSnapshot(url: string): void {
|
|
19
|
+ if (url[0] === '/') {
|
|
20
|
+ url = url.substring(1);
|
|
21
|
+ }
|
|
22
|
+ url = url.replace(/\//g, '_');
|
|
23
|
+ if (SimpleReuseStrategy.routeCache.has(url)) {
|
|
24
|
+ SimpleReuseStrategy.routeCache.delete(url);
|
|
25
|
+ }
|
|
26
|
+ SimpleReuseStrategy.waitDelete = url;
|
|
27
|
+ }
|
|
28
|
+
|
|
29
|
+ /**
|
|
30
|
+ * 用于清空路由快照
|
|
31
|
+ */
|
|
32
|
+ public static clearRouteSnapshot(): void {
|
|
33
|
+ SimpleReuseStrategy.routeCache.clear();
|
|
34
|
+ SimpleReuseStrategy.waitDelete = null;
|
|
35
|
+ }
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+ /**
|
|
39
|
+ * 基于路由数据确定路由是否应该分离。
|
|
40
|
+ * 表示对所有路由允许复用 如果有路由不想利用可以在这加一些业务逻辑判断,这里判断路由是否有 keepAlive 数据判断是否复用。
|
|
41
|
+ *
|
|
42
|
+ * @param {ActivatedRouteSnapshot} route - 要检查分离的路由快照。
|
|
43
|
+ * @return {boolean} 如果应该分离路由则返回true,否则返回 false。
|
|
44
|
+ */
|
12
|
45
|
public shouldDetach(route: ActivatedRouteSnapshot): boolean {
|
13
|
|
- return route.routeConfig && route.routeConfig.data && route.routeConfig.data.reuse === true;
|
|
46
|
+ return route.data.reuse;
|
14
|
47
|
}
|
15
|
48
|
|
16
|
|
- /** 当路由离开时会触发。按path作为key存储路由快照&组件当前实例对象 */
|
|
49
|
+
|
|
50
|
+ /**
|
|
51
|
+ * 当路由离开时会触发, 按 path 作为 key 存储路由快照组件当前实例对象
|
|
52
|
+ * 如果路由配置为‘’,则出现Cannot reattach ActivatedRouteSnapshot created from a different route问题
|
|
53
|
+ *
|
|
54
|
+ * @param {ActivatedRouteSnapshot} route - 用于获取完整路由 URL 的路由快照。
|
|
55
|
+ * @param {DetachedRouteHandle} handle - 要存储的路由处理程逻辑。
|
|
56
|
+ * @return {void}
|
|
57
|
+ */
|
17
|
58
|
public store(route: ActivatedRouteSnapshot, handle: DetachedRouteHandle): void {
|
18
|
|
- if (SimpleReuseStrategy.waitDelete && SimpleReuseStrategy.waitDelete === this.getRouteUrl(route)) {
|
19
|
|
- // 如果待删除是当前路由则不存储快照
|
|
59
|
+ const url = this.getFullRouteUrl(route);
|
|
60
|
+ if (SimpleReuseStrategy.waitDelete && SimpleReuseStrategy.waitDelete === url) {
|
|
61
|
+ // 如果待删除是当前路由,且未存储过则不存储快照
|
20
|
62
|
SimpleReuseStrategy.waitDelete = null;
|
21
|
63
|
return;
|
22
|
64
|
}
|
23
|
|
- SimpleReuseStrategy.handlers[this.getRouteUrl(route)] = handle;
|
|
65
|
+ SimpleReuseStrategy.routeCache.set(url, handle);
|
24
|
66
|
}
|
25
|
67
|
|
26
|
|
- /** 若 path 在缓存中有的都认为允许还原路由 */
|
|
68
|
+
|
|
69
|
+ /**
|
|
70
|
+ * 根据 URL 确定是否应该附加路由。
|
|
71
|
+ * 若 URL 在缓存中有的都认为允许还原路由
|
|
72
|
+ *
|
|
73
|
+ * @param {ActivatedRouteSnapshot} route - 要检查的路由快照。
|
|
74
|
+ * @return {boolean} 是否应该附加路由。
|
|
75
|
+ */
|
27
|
76
|
public shouldAttach(route: ActivatedRouteSnapshot): boolean {
|
28
|
|
- return !!SimpleReuseStrategy.handlers[this.getRouteUrl(route)];
|
|
77
|
+ const url = this.getFullRouteUrl(route);
|
|
78
|
+ return SimpleReuseStrategy.routeCache.has(url);
|
29
|
79
|
}
|
30
|
80
|
|
31
|
|
- /** 从缓存中获取快照,若无则返回nul */
|
32
|
|
- public retrieve(route: ActivatedRouteSnapshot): DetachedRouteHandle {
|
33
|
|
- if (!route.routeConfig) {
|
34
|
|
- return null;
|
35
|
|
- }
|
36
|
81
|
|
37
|
|
- return SimpleReuseStrategy.handlers[this.getRouteUrl(route)];
|
|
82
|
+ /**
|
|
83
|
+ * 从缓存中获取快照,若无则返回 null
|
|
84
|
+ *
|
|
85
|
+ * @param {ActivatedRouteSnapshot} route - 要检查的路由快照
|
|
86
|
+ * @return {SimpleDetachedRouteHandle} SimpleDetachedRouteHandle
|
|
87
|
+ */
|
|
88
|
+ public retrieve(route: ActivatedRouteSnapshot): SimpleDetachedRouteHandle {
|
|
89
|
+ const url = this.getFullRouteUrl(route);
|
|
90
|
+ let handle = SimpleReuseStrategy.routeCache.has(url)
|
|
91
|
+ ? SimpleReuseStrategy.routeCache.get(url)
|
|
92
|
+ : null;
|
|
93
|
+ handle = handle ? handle : null;
|
|
94
|
+ return handle;
|
38
|
95
|
}
|
39
|
96
|
|
40
|
|
- /** 进入路由触发,判断是否同一路由 */
|
|
97
|
+ /**
|
|
98
|
+ * 进入路由时触发,根据将来和当前路由配置和参数的比较确定当前路由是否应该重用。
|
|
99
|
+ *
|
|
100
|
+ * @param {ActivatedRouteSnapshot} future - 将来的路由快照。
|
|
101
|
+ * @param {ActivatedRouteSnapshot} curr - 当前路由快照。
|
|
102
|
+ * @return {boolean} 如果应该重用路由,则返回 true,否则返回 false。
|
|
103
|
+ */
|
41
|
104
|
public shouldReuseRoute(future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot): boolean {
|
42
|
|
- return future.routeConfig === curr.routeConfig &&
|
43
|
|
- JSON.stringify(future.params) === JSON.stringify(curr.params);
|
|
105
|
+ return (
|
|
106
|
+ future.routeConfig === curr.routeConfig &&
|
|
107
|
+ JSON.stringify(future.params) === JSON.stringify(curr.params)
|
|
108
|
+ );
|
44
|
109
|
}
|
45
|
110
|
|
46
|
|
- private getRouteUrl(route: ActivatedRouteSnapshot) {
|
47
|
|
- return route['_routerState'].url.replace(/\//g, '_');
|
|
111
|
+ /**
|
|
112
|
+ * 基于提供的 ActivatedRouteSnapshot 获取完整的路由 URL。
|
|
113
|
+ *
|
|
114
|
+ * @param {ActivatedRouteSnapshot} route - 用于生成完整路由 URL 的 ActivatedRouteSnapshot
|
|
115
|
+ * @return {string} 过滤、连接和替换字符后的完整路由URL。
|
|
116
|
+ */
|
|
117
|
+ private getFullRouteUrl(route: ActivatedRouteSnapshot): string {
|
|
118
|
+ return this.getFullRouteUrlPaths(route).filter(Boolean).join('/').replace(/\//g, '_');
|
48
|
119
|
}
|
49
|
120
|
|
50
|
|
- public static deleteRouteSnapshot(url: string): void {
|
51
|
|
- const key = url.replace(/\//g, '_');
|
52
|
|
- if (SimpleReuseStrategy.handlers[key]) {
|
53
|
|
- delete SimpleReuseStrategy.handlers[key];
|
54
|
|
- } else {
|
55
|
|
- SimpleReuseStrategy.waitDelete = key;
|
56
|
|
- }
|
|
121
|
+ /**
|
|
122
|
+ * 基于提供的 ActivatedRouteSnapshot 获取完整的路由 URL 的 paths。
|
|
123
|
+ *
|
|
124
|
+ * @param {ActivatedRouteSnapshot} route - 用于生成完整路由 URL 的 ActivatedRouteSnapshot
|
|
125
|
+ * @return {string []}
|
|
126
|
+ */
|
|
127
|
+ private getFullRouteUrlPaths(route: ActivatedRouteSnapshot): string[] {
|
|
128
|
+ const paths = route.url.map(urlSegment => urlSegment.path);
|
|
129
|
+ return route.parent ? [...this.getFullRouteUrlPaths(route.parent), ...paths] : paths;
|
57
|
130
|
}
|
58
|
131
|
}
|