用于实现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) });
相关文章
相关标签/搜索