用於實現tab頁籤切換頁面的angular路由複用策略

使用場景

打開菜單頁面的時候,出現對應頁面的頁籤。切換頁籤,原來的頁面信息狀態保留,關閉頁籤則保留的信息刪除。使用路由複用策略,保存路由快照。
實現過程

一、在app.module.ts註冊api

providers: [ { provide: RouteReuseStrategy, useClass: CustomReuseStrategy } ], 

二、新建RouteReuseStrategy數組

新建一個CustomReuseStrategy.ts

貼上代碼(解決了位於三級菜單的頁面與位於一級菜單或者二級菜單沒法跳轉的問題以後的代碼)緩存

import {ActivatedRouteSnapshot, DetachedRouteHandle, RouteReuseStrategy} from '@angular/router'; import {Injectable} from '@angular/core'; interface IRouteConfigData { reuse: boolean; } interface ICachedRoute { handle: DetachedRouteHandle; data: IRouteConfigData; } @Injectable() export class AppReuseStrategy implements RouteReuseStrategy { private static routeCache = new Map<string, ICachedRoute>(); private static waitDelete: string; // 當前頁未進行存儲時須要刪除 private static currentDelete: string; // 當前頁存儲過期須要刪除 /** 進入路由觸發,判斷是不是同一路由 */ shouldReuseRoute(future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot): boolean { return future.routeConfig === curr.routeConfig; } /** 表示對全部路由容許複用 若是你有路由不想利用能夠在這加一些業務邏輯判斷,這裏判斷是否有data數據判斷是否複用 */ shouldDetach(route: ActivatedRouteSnapshot): boolean { if (!route.data.keep) { return false; } if (!route.routeConfig || route.routeConfig.loadChildren) { return false; } return true; } /** 當路由離開時會觸發。按path做爲key存儲路由快照&組件當前實例對象 */ store(route: ActivatedRouteSnapshot, handle: DetachedRouteHandle): void { const url = this.getFullRouteUrl(route); const data = this.getRouteData(route); if (AppReuseStrategy.waitDelete && AppReuseStrategy.waitDelete === url) { // 若是待刪除是當前路由,且未存儲過則不存儲快照 AppReuseStrategy.waitDelete = null; return null; } else { // 若是待刪除是當前路由,且存儲過則不存儲快照 if (AppReuseStrategy.currentDelete && AppReuseStrategy.currentDelete === url) { AppReuseStrategy.currentDelete = null; return null; } else { AppReuseStrategy.routeCache.set(url, {handle, data}); this.addRedirectsRecursively(route); } } } /** 若 path 在緩存中有的都認爲容許還原路由 */ shouldAttach(route: ActivatedRouteSnapshot): boolean { const url = this.getFullRouteUrl(route); return AppReuseStrategy.routeCache.has(url); } /** 從緩存中獲取快照,若無則返回nul */ retrieve(route: ActivatedRouteSnapshot): DetachedRouteHandle { const url = this.getFullRouteUrl(route); const data = this.getRouteData(route); return data && AppReuseStrategy.routeCache.has(url) ? AppReuseStrategy.routeCache.get(url).handle : null; } private addRedirectsRecursively(route: ActivatedRouteSnapshot): void { const config = route.routeConfig; if (config) { if (!config.loadChildren) { const routeFirstChild = route.firstChild; const routeFirstChildUrl = routeFirstChild ? this.getRouteUrlPaths(routeFirstChild).join('/') : ''; const childConfigs = config.children; if (childConfigs) { const childConfigWithRedirect = childConfigs.find(c => c.path === '' && !!c.redirectTo); if (childConfigWithRedirect) { childConfigWithRedirect.redirectTo = routeFirstChildUrl; } } } route.children.forEach(childRoute => this.addRedirectsRecursively(childRoute)); } } private getFullRouteUrl(route: ActivatedRouteSnapshot): string { return this.getFullRouteUrlPaths(route).filter(Boolean).join('/').replace('/', '_'); } private getFullRouteUrlPaths(route: ActivatedRouteSnapshot): string[] { const paths = this.getRouteUrlPaths(route); return route.parent ? [...this.getFullRouteUrlPaths(route.parent), ...paths] : paths; } private getRouteUrlPaths(route: ActivatedRouteSnapshot): string[] { return route.url.map(urlSegment => urlSegment.path); } private getRouteData(route: ActivatedRouteSnapshot): IRouteConfigData { return route.routeConfig && route.routeConfig.data as IRouteConfigData; } /** 用於刪除路由快照*/ public static deleteRouteSnapshot(url: string): void { let arr: any = [] arr = url.split('?') url = arr[0] if (url[0] === '/') { url = url.substring(1); } url = url.replace('/', '_'); if (AppReuseStrategy.routeCache.has(url)) { AppReuseStrategy.routeCache.delete(url); AppReuseStrategy.currentDelete = url; } else { AppReuseStrategy.waitDelete = url; } } } 
附上相關API文檔:
   [RouteReuseStrategy](https://www.angular.cn/api/router/RouteReuseStrategy)

三、關閉頁籤的時候,同時刪除快照app

解決辦法:在實現頁籤的頁面,關閉按鈕那裏,刪除頁籤數組以後,加入如下代碼:
// link就是當前關閉頁面的路由 setTimeout(()=>{ AppReuseStrategy.deleteRouteSnapshot(link); }, 0) 

四、其餘ide

值得注意的是,若是頁面中有定時器,離開頁面的時候,須要暫時刪除該定時器。
但保存路由快照以後,離開該頁面的時候,不通過ngOnDestroy。
解決辦法:
this.router.events.filter(event => event instanceof NavigationEnd) .subscribe((event) => { // 路由data的標題 clearInterval(this.interval) });
相關文章
相關標籤/搜索