Angular 中跨分模块后路由复用问题
当我们的 Angular
应用越来越大后,就需要考虑使用模块或者直接使用库来将解体应用,使用时进来懒加载,加快访问速度。当跨分模块后,普通的路由复用策略就是失效,需要额外的解决方法。
前提
angular 使用路由复用 这篇文章里介绍了如何使用路由复用。
angular 划分库 这篇文章里介绍了如何使用库的方式来减小应用复杂性。
问题
使用懒加载后,应用大概率会抛出 Cannot reattach ActivatedRouteSnapshot created from a different route 这个错误,这主要是因为,使用模块后,每个模块都可能会有 ''
这个路径来做默认路由,系统无法正确找到路由快照。
解决
解决方法也比较简单,既然是因为 key
重复,那就使用不会重复的名称来作为 key
就行。我这边的解决方案,是去定义一个自定义的结构来存储数据,Route
类型中提供了属性data
,就是下面代码里的 data
。
const routes: Routes = [
{
path: 'login',
component: LoginComponent,
data: { url: '/login' },
},
];
复用策略中也使用 data
中的 url
来实现快照的存储和还原。
import { RouteReuseStrategy, , ActivatedRouteSnapshot, DetachedRouteHandle } from '@angular/router';
export class AppRouteReuseStrategy implements RouteReuseStrategy {
public static handlers: Map<string, DetachedRouteHandle | undefined> = new Map();
constructor() { }
public shouldDetach(_route: ActivatedRouteSnapshot): boolean {
return true;
}
public store(
route: ActivatedRouteSnapshot,
handle: DetachedRouteHandle
): void {
if (!route.data) return;
AppRouteReuseStrategy.handlers.set(route.data['url'], handle);
}
public shouldAttach(route: ActivatedRouteSnapshot): boolean {
return !!route.routeConfig && !!AppRouteReuseStrategy.handlers.get(route.data['url']);
}
public retrieve(route: ActivatedRouteSnapshot): DetachedRouteHandle | null {
if (!route.data || !AppRouteReuseStrategy.handlers.has(route.data['url'])) return null;
return AppRouteReuseStrategy.handlers.get(route.data['url'])!;
}
public shouldReuseRoute(
future: ActivatedRouteSnapshot,
curr: ActivatedRouteSnapshot
): boolean {
return future.routeConfig === curr.routeConfig;
}
}