用于实现tab页签切换页面的angular路由复用策略

使用场景

打开菜单页面的时候,出现对应页面的页签。切换页签,原来的页面信息状态保留,关闭页签则保留的信息删除。使用路由复用策略,保存路由快照。
实现过程

1、在app.module.ts注册

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

2、新建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)

3、关闭页签的时候,同时删除快照

解决办法:在实现页签的页面,关闭按钮那里,删除页签数组之后,加入以下代码:
    // link就是当前关闭页面的路由
    setTimeout(()=>{
      AppReuseStrategy.deleteRouteSnapshot(link);
    }, 0) 

4、其他

值得注意的是,如果页面中有定时器,离开页面的时候,需要暂时删除该定时器。
但保存路由快照之后,离开该页面的时候,不经过ngOnDestroy。
解决办法:
this.router.events.filter(event => event instanceof NavigationEnd)
      .subscribe((event) => { // 路由data的标题 clearInterval(this.interval) });

转载于:https://www.cnblogs.com/Zhang-jin/p/11064612.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值