浏览代码

页签修复

seimin 1 月之前
父节点
当前提交
63c4b689f2

+ 40 - 48
src/app/SimpleReuseStrategy.ts

@@ -1,66 +1,58 @@
1
-import { RouteReuseStrategy, ActivatedRouteSnapshot, DetachedRouteHandle, UrlSegment } from '@angular/router';
1
+import {RouteReuseStrategy, DefaultUrlSerializer, ActivatedRouteSnapshot, DetachedRouteHandle} from '@angular/router';
2
 
2
 
3
+/**
4
+ * 路由复用策略
5
+ */
3
 export class SimpleReuseStrategy implements RouteReuseStrategy {
6
 export class SimpleReuseStrategy implements RouteReuseStrategy {
4
-  static cacheRouters = new Map<string, DetachedRouteHandle>();
5
 
7
 
6
-  public static deleteRouteCache(url): void {
7
-    if (SimpleReuseStrategy.cacheRouters.has(url)) {
8
-      const handle: any = SimpleReuseStrategy.cacheRouters.get(url);
9
-      try {
10
-        handle.componentRef.destory();
11
-      } catch (e) { }
12
-      SimpleReuseStrategy.cacheRouters.delete(url);
13
-    }
8
+  public static handlers: { [key: string]: DetachedRouteHandle } = {};
9
+  private static waitDelete: string;
10
+
11
+  /** 表示对所有路由允许复用 如果你有路由不想利用可以在这加一些业务逻辑判断 */
12
+  public shouldDetach(route: ActivatedRouteSnapshot): boolean {
13
+    return route.routeConfig && route.routeConfig.data && route.routeConfig.data.reuse === true;
14
   }
14
   }
15
 
15
 
16
-  public static deleteAllRouteCache(): void {
17
-    SimpleReuseStrategy.cacheRouters.forEach((handle: any, key) => {
18
-      SimpleReuseStrategy.deleteRouteCache(key);
19
-    });
16
+  /** 当路由离开时会触发。按path作为key存储路由快照&组件当前实例对象 */
17
+  public store(route: ActivatedRouteSnapshot, handle: DetachedRouteHandle): void {
18
+    if (SimpleReuseStrategy.waitDelete && SimpleReuseStrategy.waitDelete === this.getRouteUrl(route)) {
19
+      // 如果待删除是当前路由则不存储快照
20
+      SimpleReuseStrategy.waitDelete = null;
21
+      return;
22
+    }
23
+    SimpleReuseStrategy.handlers[this.getRouteUrl(route)] = handle;
20
   }
24
   }
21
 
25
 
22
-  // one 进入路由触发,是否同一路由时复用路由
23
-  shouldReuseRoute(future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot): boolean {
24
-    return future.routeConfig === curr.routeConfig &&
25
-      JSON.stringify(future.params) === JSON.stringify(curr.params);
26
+  /** 若 path 在缓存中有的都认为允许还原路由 */
27
+  public shouldAttach(route: ActivatedRouteSnapshot): boolean {
28
+    return !!SimpleReuseStrategy.handlers[this.getRouteUrl(route)];
26
   }
29
   }
27
 
30
 
28
-  // 获取存储路由
29
-  retrieve(route: ActivatedRouteSnapshot): DetachedRouteHandle {
30
-    const url = this.getFullRouteURL(route);
31
-    if (route.data.reuse && SimpleReuseStrategy.cacheRouters.has(url)) {
32
-      return SimpleReuseStrategy.cacheRouters.get(url);
33
-    } else {
31
+  /** 从缓存中获取快照,若无则返回nul */
32
+  public retrieve(route: ActivatedRouteSnapshot): DetachedRouteHandle {
33
+    if (!route.routeConfig) {
34
       return null;
34
       return null;
35
     }
35
     }
36
-  }
37
 
36
 
38
-  // 是否允许复用路由
39
-  shouldDetach(route: ActivatedRouteSnapshot): boolean {
40
-    return Boolean(route.data.reuse);
41
-  }
42
-  // 当路由离开时会触发,存储路由
43
-  store(route: ActivatedRouteSnapshot, handle: DetachedRouteHandle): void {
44
-    const url = this.getFullRouteURL(route);
45
-    SimpleReuseStrategy.cacheRouters.set(url, handle);
46
-  }
47
-  //  是否允许还原路由
48
-  shouldAttach(route: ActivatedRouteSnapshot): boolean {
49
-    const url = this.getFullRouteURL(route);
50
-    return Boolean(route.data.reuse) && SimpleReuseStrategy.cacheRouters.has(url);
37
+    return SimpleReuseStrategy.handlers[this.getRouteUrl(route)];
51
   }
38
   }
52
 
39
 
53
-  // 获取当前路由url
54
-  private getFullRouteURL(route: ActivatedRouteSnapshot): string {
55
-    const { pathFromRoot } = route;
56
-    let fullRouteUrlPath: string[] = [];
57
-    pathFromRoot.forEach((item: ActivatedRouteSnapshot) => {
58
-      fullRouteUrlPath = fullRouteUrlPath.concat(this.getRouteUrlPath(item));
59
-    });
60
-    return `/${fullRouteUrlPath.join('/')}`;
40
+  /** 进入路由触发,判断是否同一路由 */
41
+  public shouldReuseRoute(future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot): boolean {
42
+    return future.routeConfig === curr.routeConfig &&
43
+      JSON.stringify(future.params) === JSON.stringify(curr.params);
44
+  }
61
 
45
 
46
+  private getRouteUrl(route: ActivatedRouteSnapshot) {
47
+    return route['_routerState'].url.replace(/\//g, '_');
62
   }
48
   }
63
-  private getRouteUrlPath(route: ActivatedRouteSnapshot) {
64
-    return route.url.map(urlSegment => urlSegment.path);
49
+
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
+    }
65
   }
57
   }
66
 }
58
 }

+ 12 - 11
src/app/views/new-statistics/maintenance-statistics/maintenance-statistics.component.ts

@@ -1,7 +1,6 @@
1
 import { ActivatedRoute, Router } from '@angular/router';
1
 import { ActivatedRoute, Router } from '@angular/router';
2
 import { Component, OnInit, OnDestroy } from "@angular/core";
2
 import { Component, OnInit, OnDestroy } from "@angular/core";
3
 import { ToolService } from 'src/app/services/tool.service';
3
 import { ToolService } from 'src/app/services/tool.service';
4
-import { SimpleReuseStrategy } from '../../../SimpleReuseStrategy';
5
 import { TabService } from '../services/tab.service';
4
 import { TabService } from '../services/tab.service';
6
 @Component({
5
 @Component({
7
   selector: "app-maintenance-statistics",
6
   selector: "app-maintenance-statistics",
@@ -27,8 +26,7 @@ export class MaintenanceStatisticsComponent implements OnInit, OnDestroy {
27
 
26
 
28
   ngOnDestroy(){
27
   ngOnDestroy(){
29
     this.sessionRemove();
28
     this.sessionRemove();
30
-    this.tabService.tabs = [];
31
-    SimpleReuseStrategy.deleteAllRouteCache();
29
+    this.tabService.deleteAllRouteSnapshot();
32
   }
30
   }
33
 
31
 
34
   getMenuList(){
32
   getMenuList(){
@@ -41,20 +39,23 @@ export class MaintenanceStatisticsComponent implements OnInit, OnDestroy {
41
   clickMenu(data){
39
   clickMenu(data){
42
     this.activeMenuId = data.id;
40
     this.activeMenuId = data.id;
43
     this.secondMenuList = this.menuList.find(v => v.id == this.activeMenuId).childrens || [];
41
     this.secondMenuList = this.menuList.find(v => v.id == this.activeMenuId).childrens || [];
44
-    this.tabService.tabs = [];
45
-    SimpleReuseStrategy.deleteAllRouteCache();
46
-    this.secondMenuList.length && this.clickSecondMenu(this.secondMenuList[0]);
42
+    // this.tabService.deleteAllRouteSnapshot();
43
+    console.log(this.tabService.tabs)
44
+    let activeTab = this.tabService.tabs.find(v => v.active);
45
+    // return;
46
+    if(this.secondMenuList.length){
47
+      if(activeTab.path === `/newStatistics/${this.route.parent.snapshot.routeConfig.path}/${this.secondMenuList[0].link}`){
48
+        this.clickSecondMenu(this.secondMenuList[0]);
49
+      }else{
50
+        this.activeSecondMenuLink = activeTab.path.split('/').reverse()[0];
51
+      }
52
+    }
47
   }
53
   }
48
 
54
 
49
   // 点击二级菜单
55
   // 点击二级菜单
50
   activeSecondMenuLink:string;
56
   activeSecondMenuLink:string;
51
   clickSecondMenu(data){
57
   clickSecondMenu(data){
52
     this.activeSecondMenuLink = data.link;
58
     this.activeSecondMenuLink = data.link;
53
-    let hasCache = SimpleReuseStrategy.cacheRouters.has(`/newStatistics/${this.route.parent.snapshot.routeConfig.path}/${this.activeSecondMenuLink}`);
54
-    console.log('tabs', this.tabService.tabs);
55
-    console.log('cacheRouters', SimpleReuseStrategy.cacheRouters);
56
-    console.log('cacheRouters', hasCache);
57
-    !hasCache && SimpleReuseStrategy.deleteRouteCache(`/newStatistics/${this.route.parent.snapshot.routeConfig.path}/${this.activeSecondMenuLink}`);
58
     this.router.navigate([`/newStatistics/${this.route.parent.snapshot.routeConfig.path}/${this.activeSecondMenuLink}`], { replaceUrl: true });
59
     this.router.navigate([`/newStatistics/${this.route.parent.snapshot.routeConfig.path}/${this.activeSecondMenuLink}`], { replaceUrl: true });
59
   }
60
   }
60
 
61
 

+ 17 - 7
src/app/views/new-statistics/services/tab.service.ts

@@ -19,10 +19,20 @@ export class TabService {
19
     this.router.events
19
     this.router.events
20
       .pipe(filter(event => event instanceof NavigationEnd))
20
       .pipe(filter(event => event instanceof NavigationEnd))
21
       .subscribe((event: NavigationEnd) => {
21
       .subscribe((event: NavigationEnd) => {
22
-        event.urlAfterRedirects.startsWith('/newStatistics/') && this.updateTabs(event.urlAfterRedirects);
22
+      	console.log('event:', event)
23
+        if(event.urlAfterRedirects.startsWith('/newStatistics/')){
24
+          this.updateTabs(event.urlAfterRedirects);
25
+        }
23
       });
26
       });
24
   }
27
   }
25
 
28
 
29
+  public deleteAllRouteSnapshot(){
30
+    this.tabs.forEach(v => {
31
+      SimpleReuseStrategy.deleteRouteSnapshot(v.path);
32
+    })
33
+    this.tabs = [];
34
+  }
35
+
26
   private updateTabs(url: string) {
36
   private updateTabs(url: string) {
27
     const normalizedUrl = this.getNormalizedUrl(url);
37
     const normalizedUrl = this.getNormalizedUrl(url);
28
     const existingTab = this.tabs.find(t => t.path === normalizedUrl);
38
     const existingTab = this.tabs.find(t => t.path === normalizedUrl);
@@ -60,7 +70,6 @@ export class TabService {
60
 
70
 
61
   closeTab(path: string): any {
71
   closeTab(path: string): any {
62
     console.log('path:', path)
72
     console.log('path:', path)
63
-    SimpleReuseStrategy.deleteRouteCache(path);
64
 
73
 
65
     const index = this.tabs.findIndex(t => t.path === path);
74
     const index = this.tabs.findIndex(t => t.path === path);
66
     if (index === -1) return;
75
     if (index === -1) return;
@@ -84,6 +93,7 @@ export class TabService {
84
 
93
 
85
     // 执行删除
94
     // 执行删除
86
     this.tabs.splice(index, 1);
95
     this.tabs.splice(index, 1);
96
+    SimpleReuseStrategy.deleteRouteSnapshot(path);
87
 
97
 
88
     // 设置新激活页签
98
     // 设置新激活页签
89
     if (newActiveTab) {
99
     if (newActiveTab) {
@@ -108,16 +118,16 @@ export class TabService {
108
 
118
 
109
   closeOtherTabs(keepTab: Tab): void {
119
   closeOtherTabs(keepTab: Tab): void {
110
     // 强制激活当前右键页签
120
     // 强制激活当前右键页签
111
-    this.tabs = this.tabs.filter(t => t.path === keepTab.path);
112
-    keepTab.active = true;
113
-    this.currentTab = keepTab;
114
-
115
     this.tabs.forEach(v => {
121
     this.tabs.forEach(v => {
116
       if (v.path !== keepTab.path) {
122
       if (v.path !== keepTab.path) {
117
-        SimpleReuseStrategy.deleteRouteCache(v.path);
123
+        SimpleReuseStrategy.deleteRouteSnapshot(v.path);
118
       }
124
       }
119
     })
125
     })
120
 
126
 
127
+    this.tabs = this.tabs.filter(t => t.path === keepTab.path);
128
+    keepTab.active = true;
129
+    this.currentTab = keepTab;
130
+
121
     // 触发路由跳转
131
     // 触发路由跳转
122
     this.router.navigate([keepTab.path], {
132
     this.router.navigate([keepTab.path], {
123
       replaceUrl: true
133
       replaceUrl: true