践行angular我爱编程

angular的路由复用RouteReuseStrategy

2018-05-24  本文已影响79人  Gary嘉骏
前言

在内部用的后台中,有很多用户喜欢在某已路由内操作表单的同时去其它路由页面查询资料。此时,普通的angular应用在各路由页面跳转的时候默认不会保存路由状态,所以用户未保存的表单资料在离开路由时就被销毁。要解决此问题,就要引入路由复用策略,此策略由angular2的版本就存在,但目前好像还是实验性API。但在API页面可以查到, 它的定义为

abstract class RouteReuseStrategy {
  abstract shouldDetach(route: ActivatedRouteSnapshot): boolean
  abstract store(route: ActivatedRouteSnapshot, handle: DetachedRouteHandle | null): void
  abstract shouldAttach(route: ActivatedRouteSnapshot): boolean
  abstract retrieve(route: ActivatedRouteSnapshot): DetachedRouteHandle | null
  abstract shouldReuseRoute(future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot): boolean
}

定义的的顺序就是复用的逻辑,离开某路由页面时,shouldDetach觉得可复用后,store去保存路由,再次进入页面时,shouldAttach判断下可通过去缓存中拿到复用的路由后,retrieve返回路由缓存,最后shouldReuseRoute对获得缓存路由与将进入的路由进行比对,一致通过则使用缓存的路由复现之前的画面。

浅显但有点难度

网上有好几个版本,但运行起来会报错(error:Cannot reattach ActivatedRouteSnapshot with a different number of children E),报错内容就是angular判断缓存的路由与你配置的路由不一致,不给跳转。所以根本原因就是缓存的时候的唯一key获取不对,key的内容当然是唯一的路由地址,但ActivatedRouteSnapshot的对象不会直接给你,需要自己去拼接,如大部分的直接用route.routeConfig.path这就明显不唯一,这只是你配置的时候的一部分。有些又直接用带_的对象,首先这是私有的,angular不希望你去使用,而且该参数不一定对应正确的DetachedRouteHandle对象。查看an-alian项目时,才知道正确的key获取方法。如下:

getUrl(route: ActivatedRouteSnapshot) {
    let /** @type {?} */ next = this.getTruthRoute(route);
    let /** @type {?} */ segments = [];
    while (next) {
      segments.push(next.url.join('/'));
      next = next.parent;
    }
    let /** @type {?} */ url = segments
      .filter(function(i) {
        return i;
      })
      .reverse()
      .join('/');
    return url;
  }
  getTruthRoute(route: ActivatedRouteSnapshot) {
    let /** @type {?} */ next = route;
    while (next.firstChild) {
      next = next.firstChild;
    }
    return next;
  }

getTruthRoute是为了保证每次都从最后的子路由开始获取,你去测试就会发现,两懒加载模块间跳转时,进入的ActivatedRouteSnapshot是中间的路由配置,需要找回最后的child。然后一步一步的往parent去拼接,最后得到真正唯一的key。

最后

有初步探索过的人应该就能把此复用策略跑起来了,完整代码就不贴了,也就是如何报错缓存与获取缓存的问题。谢谢

上一篇下一篇

猜你喜欢

热点阅读