资讯专栏INFORMATION COLUMN

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

wendux / 3273人阅读

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

关于路由复用策略网上的文章很多,大多是讲如何实现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;
    }
}
关键概念解释
开始文章前我们先了解几个观念概念

我们的路由是棵树RouterModule.forRoot(Routes)RouterModule.forChild(Routes)这些配置最后形成一个完整的路由树,路由树有个根是没有routeConfig的,routeConfig是我们写的每个route

路由节点,一个路径是由几个路由节点组成,有的route配置了component,有的则没有

future下一路由, curr当前路由,切换路由时,我们在下文用future表示下一路由,curr表示当前路由

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

shouldReuseRoute(future, curr)

retrieve(route)

shouldDetach(route)

store(route, detachedTree)

shouldAttach(route)

retrieve,取决一上一步的返回值

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 = 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 {
     if (!!route.firstChild) {
          return null;
        }
    return CustomerReuseStrategy.handlers.get(route.routeConfig);
  }
  store(route: ActivatedRouteSnapshot, handle: DetachedRouteHandle): void {
    CustomerReuseStrategy.handlers.set(route.routeConfig, handle);
  }
}

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

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

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/100362.html

相关文章

  • 关于Vue2一些值得推荐的文章 -- 五、六月份

    摘要:五六月份推荐集合查看最新的请点击集前端最近很火的框架资源定时更新,欢迎一下。苏幕遮燎沈香宋周邦彦燎沈香,消溽暑。鸟雀呼晴,侵晓窥檐语。叶上初阳乾宿雨,水面清圆,一一风荷举。家住吴门,久作长安旅。五月渔郎相忆否。小楫轻舟,梦入芙蓉浦。 五、六月份推荐集合 查看github最新的Vue weekly;请::点击::集web前端最近很火的vue2框架资源;定时更新,欢迎 Star 一下。 苏...

    sutaking 评论0 收藏0
  • 关于Vue2一些值得推荐的文章 -- 五、六月份

    摘要:五六月份推荐集合查看最新的请点击集前端最近很火的框架资源定时更新,欢迎一下。苏幕遮燎沈香宋周邦彦燎沈香,消溽暑。鸟雀呼晴,侵晓窥檐语。叶上初阳乾宿雨,水面清圆,一一风荷举。家住吴门,久作长安旅。五月渔郎相忆否。小楫轻舟,梦入芙蓉浦。 五、六月份推荐集合 查看github最新的Vue weekly;请::点击::集web前端最近很火的vue2框架资源;定时更新,欢迎 Star 一下。 苏...

    khs1994 评论0 收藏0
  • Angular2 VS Angular4 深度对比:特性、性能

    摘要:的特性和性能是的超集,用于帮助的开发。注解提供了连接元数据和功能的工具。通过在库中提供基本信息可以调用函数或创建类的实例来检查相关元数据,从而简化了对象实例的构建。停用它会响应跳出旧控制器的成功事件。 showImg(https://segmentfault.com/img/bVSqTU?w=850&h=460); 在Web应用开发领域,Angular被认为是最好的开源JavaScri...

    孙淑建 评论0 收藏0
  • Angularjs 1 深度解析:组件化编程

    摘要:一个高度可复用的组件则可以被称为控件,是可以单独投稿项目库的。行为的定制化通过参数绑定实现组件行为的定制化。组件被销毁时调用。当有组件复用的情况时请使用标识指定接收对象模型另外最好给事件名添加组件前缀。 转自自己在开源中国的博客:https://my.oschina.net/u/7247... angular 1 也要面向组件编程 前端组件化是前端开发模式中一个不可逆转的趋势,三大主要...

    caohaoyu 评论0 收藏0

发表评论

0条评论

wendux

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<