RouteReuseStrategy angular路由复用策略详解,深度刨析路由复用策略

简介: 关于路由复用策略网上的文章很多,大多是讲如何实现tab标签切换历史数据,至于如何复用的原理讲的都比较朦胧,代码样例也很难适用各种各样的路由配置,比如懒加载模式下多级嵌套路由出口网上的大部分代码都会报错。
关于路由复用策略网上的文章很多,大多是讲如何实现tab标签切换历史数据,至于如何复用的原理讲的都比较朦胧,代码样例也很难适用各种各样的路由配置,比如懒加载模式下多级嵌套路由出口网上的大部分代码都会报错。
我希望能通过这篇文章把如何复用路由的原理讲明白,让小伙伴能明明白白的实用路由复用策略,文字中有不详实和错误的地方欢迎小伙伴批评指正

对路由复用策略的理解

路由复用策略的是对路由的父级相同节点的组件实例的复用,我们平时看到的多级嵌套路由切换时上层路由出口的实例并不会从新实例化就是因为angular默认的路由复用策略在起作用,而我们从写路由复用策略能实现很多事情,其中之一就是实现
历史路由状态(数据)的存储,即jquery时代的tab页签和iframe实现操作历史的切换。

我一开始认为路由复用策略就是对历史路由数据的复用策略,这个错误的观念导致我对路由复用策略接口方法理解起来异常困难,不知小伙伴和我犯没犯同样的错误。观念正确了,下面就理解起来比较方便了,写路由复用策略也就比较顺手了。

下面是angular默认路由复用策略,每切换一下路由,下面代码都再默默的执行。


export class DefaultRouteReuseStrategy {
    shouldDetach(route) { return false; }
    store(route, detachedTree) { }
    shouldAttach(route) { return false; }
    retrieve(route) { return null; }
    shouldReuseRoute(future, curr) {
        return future.routeConfig === curr.routeConfig;
    }
}

关键概念解释

开始文章前我们先了解几个观念概念
  1. 我们的路由是棵树RouterModule.forRoot(Routes)RouterModule.forChild(Routes)这些配置最后形成一个完整的路由树,路由树有个根是没有routeConfig的,routeConfig是我们写的每个route
  2. 路由节点,一个路径是由几个路由节点组成,有的route配置了component,有的则没有
  3. future下一路由, curr当前路由,切换路由时,我们在下文用future表示下一路由,curr表示当前路由

路由复用策略解析

路由复用策略方法调用顺序

  1. shouldReuseRoute(future, curr)
  2. retrieve(route)
  3. shouldDetach(route)
  4. store(route, detachedTree)
  5. shouldAttach(route)
  6. retrieve,取决一上一步的返回值
  7. store(route, detachedTree),取决第五步

shouldReuseRoute

shouldReuseRoute()决定是否复用路由,根据切换的future curr的节点层级依次调用,返回值为true时表示当前节点层级路由复用,然后继续下一路由节点调用,入参为切换的下一级路由(子级)的future curr路由的节点,返回值为false时表示不在复用路由,并且不再继续调用此方法(future路由不再复用,其子级路由也不会复用,所以不需要再询问下去),root路由节点调用一次,非root路由节点调用两次这个方法,第一次比较父级节点,第二次比较当前节点,

retrieve

retrieve()接上一步奏,当当前层级路由不需要复用的时候,调用一下retrieve方法,其子级路由也会调用一下retrieve方法,如果返回的是null,那么当前路由对应的组件会实例化,这种行为一直持续到末级路由。

shouldDetach

shouldDetach是对上一路由的数据是否实现拆离,其调用开始是当前层级路由不需要复用的时候,即shouldReuseRoute()返回false的时候,如果这时候反回false,将继续到上一路由的下一层级调用shouldDetach,直到返回true或者是最末级路由后才结束对shouldDetach的调用,当返回true时就调用一次store 方法,请看下一步奏

store

store存储路分离出来的上一路由的数据,当 shouldDetach返回true时调用一次,存储应该被分离的那一层的路由的DetachedRouteHandle。注意:无论路由树上多个含有组件component路由节点,能分离出来的只能有一个,被存储的也只能有一个,感觉这种机制对使用场景有很大限制。

shouldAttach

shouldAttach是对当前路由的数据是否实现恢复(附加回来),其调用开始是当前层级路由不需要复用的时候,即shouldReuseRoute()返回false的时候,这和shouldDetach的调用时机很像,但是,并不是所有的路由层级都是有组件实例的,只有包含componentroute才会触发shouldAttach,如果反回false,将继续到当前路由的下一带有component的路由层级调用shouldAttach,直到返回true或者是最末级路由后才结束对shouldAttach
的调用,当返回true时就调用一次retrieve 方法,如果retrieve方法去获取一下当前路由的DetachedRouteHandle,返回一个DetachedRouteHandle,就再调用一次store,再保存一下retrieve返回的DetachedRouteHandle。注意注意:无论路由树上多个含有组件component路由节点,能恢复数据的只能有一个节点,这和shouldDetach是一个套路,对使用场景有很大限制。

总结·这个还是实验性的路由复用策略还是不够强大

路由复用策略这种调用机制对使用场景限制很大 ,比如多级路由出口嵌套就无法实现路由数据缓存。因为多级路由出口嵌套的应用切换路由时,前后路由会包含多个带component的路由节点,而每次对路由的存储和恢复只能存储和恢复某一个节点的component的DetachedRouteHandle,其他路由节点上的component就是被从新实例化。明白这一点后我就放弃了想写一个可以适用任何场景的路由复用策略的想法,如果有小伙伴能解决好这一业务场景,欢迎赐教。

如果这个路由复用策略可以存储一个路由上多个节点的DetachedRouteHandle,和恢复多个节点的DetachedRouteHandle,应该能解决上面是的多级路由出口嵌套场景,但不知道会不会带来别的问题。

一个路由复用策略用例

下面贴一个路由复用策略用例,应该是满足大部分人的业务要求,注意事项:只能是末级路由的缓存,且路由切换的时候路由节点上的component不能超过两个。


import {ActivatedRouteSnapshot, DetachedRouteHandle, Route, RouteReuseStrategy} from "@angular/router";

export class CustomerReuseStrategy implements RouteReuseStrategy {
  static handlers: Map<Route, DetachedRouteHandle> = new Map();
  shouldDetach(route: ActivatedRouteSnapshot): boolean {
    return !route.firstChild;
  }
  shouldAttach(route: ActivatedRouteSnapshot): boolean {
    return !!CustomerReuseStrategy.handlers.has(route.routeConfig);
  }
  shouldReuseRoute(future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot) {
    return curr.routeConfig === future.routeConfig;
  }
  retrieve(route: ActivatedRouteSnapshot): DetachedRouteHandle {
    return CustomerReuseStrategy.handlers.get(route.routeConfig);
  }
  store(route: ActivatedRouteSnapshot, handle: DetachedRouteHandle): void {
    CustomerReuseStrategy.handlers.set(route.routeConfig, handle);
  }
}

很精简,但是很好用,小伙伴可以根据自己的业务逻辑进行改造。

如果感觉这篇文章对你有帮助,请点个赞吧

来源:https://segmentfault.com/a/1190000017498510

相关文章
|
6月前
|
JavaScript 前端开发 应用服务中间件
angular引入包、路由权限配置、打包问题与nginx配置问题(简单部署)
angular引入包、路由权限配置、打包问题与nginx配置问题(简单部署)
154 0
|
1月前
|
UED
|
3月前
|
开发者 Windows Android开发
跨平台开发新选择:揭秘Uno Platform与.NET MAUI优劣对比,帮你找到最适合的框架,告别选择困难症!
【8月更文挑战第31天】本文对比了备受关注的跨平台开发框架Uno Platform与.NET MAUI的特点、优势及适用场景。Uno Platform基于WebAssembly和WebGL技术,支持Windows、iOS、Android及Web平台,而.NET MAUI由微软推出,旨在统一多种UI框架,支持Windows、iOS和Android。两者均采用C#和XAML进行开发,但在性能、平台支持及社区生态方面存在差异。Uno Platform在Web应用方面表现出色,但性能略逊于原生应用;.NET MAUI则接近原生性能,但不支持Web平台。开发者应根据具体需求选择合适的框架。
128 0
|
3月前
|
SEO 搜索推荐 数据采集
让 JSF 应用秒变搜索引擎宠儿!揭秘 SEO 优化的神奇魔法,让你的网站脱颖而出!
【8月更文挑战第31天】随着互联网的发展,搜索引擎已成为用户获取信息的主要途径,SEO 对 Web 应用至关重要。本文介绍如何提升 JavaServer Faces(JSF)应用的 SEO 友好性,包括关键词优化、网页结构优化和外部链接建设等基础知识,并提出了使用语义化 HTML 标签、优化页面标题和描述、生成静态 HTML 页面及 URL 重写等具体策略,帮助您的网站在搜索引擎中获得更高排名。
32 0
|
3月前
|
安全 开发者
精通Angular路由管理:从基础设置到高级配置,打造复杂SPA导航系统的全方位指南
【8月更文挑战第31天】在单页应用(SPA)中,路由管理至关重要。Angular通过其强大的路由模块提供灵活高效的解决方案。本文通过代码示例详细介绍如何在Angular中设置和管理路由,包括基础路由配置、懒加载、路由保护及高级配置,帮助开发者构建高效安全的导航系统,满足复杂SPA需求。随着Angular的发展,路由管理将更加完善,值得持续关注。
33 0
|
3月前
|
缓存 UED 开发者
全面加速Angular应用:从代码拆分到服务器端渲染的性能优化全攻略——深入探讨提升加载速度的有效策略
【8月更文挑战第31天】在现代Web开发中,提升应用加载速度对增强用户体验至关重要,尤其对于使用Angular框架的单页应用而言更是如此。本文通过解答五个常见问题,提供了一份全面的Angular性能优化攻略,涵盖减少初始加载时间、处理大型第三方库、优化变更检测、利用缓存以及服务器端渲染等技术。通过这些方法,开发者能够显著提升应用性能,确保流畅高效的用户体验。
53 0
|
3月前
|
JavaScript 前端开发 API
如何在 Angular 路由中使用路由解析器
如何在 Angular 路由中使用路由解析器
37 0
|
3月前
如何在 Angular 路由中使用路由守卫
如何在 Angular 路由中使用路由守卫
46 0
|
3月前
如何在 Angular 路由中使用查询参数
如何在 Angular 路由中使用查询参数
27 0
|
3月前
|
JavaScript 前端开发 测试技术
如何在 Angular 中使用懒加载路由
如何在 Angular 中使用懒加载路由
29 0