angular

解决angular路由复用懒加载不起作用的问题

2019-01-16  本文已影响176人  krock01

路由复用

路由复用主要是为了缓存一些页面的状态,例如:搜索结果,查看某一条后再回到页面依然保持原有的搜索列表结果。

非懒加载路由

即直接路由组件

path: "",
    component: LayoutComponent,
    children: [
      {
        path: "menu",
        component: MenuComponent
      },
      {
        path: "user",
        component: UserComponent
      }
    ]

非懒加载的路由策略重写

import { RouteReuseStrategy, DefaultUrlSerializer, ActivatedRouteSnapshot, DetachedRouteHandle } from '@angular/router';

export class SimpleReuseStrategy implements RouteReuseStrategy {

    public static handlers: { [key: string]: DetachedRouteHandle } = {}

    /** 表示对所有路由允许复用 如果你有路由不想利用可以在这加一些业务逻辑判断 */
    public shouldDetach(route: ActivatedRouteSnapshot): boolean {
        return true;
    }

    /** 当路由离开时会触发。按path作为key存储路由快照&组件当前实例对象 */
    public store(route: ActivatedRouteSnapshot, handle: DetachedRouteHandle): void {
        SimpleReuseStrategy.handlers[route.routeConfig.path] = handle
    }

    /** 若 path 在缓存中有的都认为允许还原路由 */
    public shouldAttach(route: ActivatedRouteSnapshot): boolean {
        return !!route.routeConfig && !!SimpleReuseStrategy.handlers[route.routeConfig.path]
    }

    /** 从缓存中获取快照,若无则返回nul */
    public retrieve(route: ActivatedRouteSnapshot): DetachedRouteHandle {
        if (!route.routeConfig) {
            return null
        }
        
        return SimpleReuseStrategy.handlers[route.routeConfig.path]
    }

    /** 进入路由触发,判断是否同一路由 */
    public shouldReuseRoute(future: ActivatedRouteSnapshot, curr: ActivatedRouteSnapshot): boolean {
        return future.routeConfig === curr.routeConfig
    }
}

在appModule中启用该自定义的路由策略

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

以上代码来源:这里

下面才是主菜:

上面的配置你可以顺利的实现路由的复用,但是大部分业务中都使用了模块懒加载(loadChildren),这时候你会发现页面复用没有效果。

路由配置

path: "",
    component: LayoutComponent,
    children: [
      {
        path: "menu",
        loadChildren: "./menu/menu.module#MenuModule",
        data: {
          key: "menu"
        }
      },
      {
        path: "user",
        loadChildren: "./user/user.module#UserModule",
        data: {
          key: "user"
        }
      }
    ]

重写路由策略

这里代码就不再重新写了,只说关键点,在懒加载的路由中,上面代码中使用的route.routeConfig.path不能用来作为关键字存储缓存(为什么?额,只是追踪了下发现能缓存页面的树结构和变量,但是不能恢复页面,那么就看shouldAttach方法,发现shouldAttach方法中route.routeConfig.path一直是空的!!!

{path: "", component: ƒ}

)。

有些人肯定注意到了新的路由配置多了个key,是的,你想的没错,把重写路由的代码中所有的route.routConfig.path 改为route.data.key
就能够解决这个问题了。

总结

这个解决办法不是唯一的,你也可以用其他方式处理这个唯一标识符,还有一点记得手动清除页面缓存(如果你刷新页面的话,当我没说), 不然页面缓存会一直存在。不会清除???懒???额,好吧,注入自定义策略SimpleReuseStrategy到你删除缓存的地方,
delete delete SimpleReuseStrategy.handlers[key];

上一篇下一篇

猜你喜欢

热点阅读