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;
  }
}
发布时间:2022-09-05
其他阅读

记录一次Unity中的同步问题

在以前做的数字孪生应用中,使用的 socket 进行定制协议开发,服务和 Unity 客户端之间可以互相进行通信,在开发时代价太大,除了正常制定数据协议外,还需要针对粘包定制切包协议。在WEB化的过程中,准备把原有的数字孪生服务端进行迁移,使用全新的 asp.net core 进行开发,双方使用 signalR 进行数据交互。

查看原文

新版本.Net关于Process.Start的问题

.Net 开发中,试用 Process.Start() 来启动一个新进程,当我们传入的是具体文件或者链接的时候,系统也会根据默认打开方式打开对应的进程。但是在新版本的 .Net 中,试用 Process.Start() 来打开文件或者链接的时候,会抛出 System.ComponentModel.Win32Exception 的错误,提示系统找不到指定的文件。

查看原文

Js使用原型链对对象进行扩展

在C#的扩展方法中,我们了解到了一种不需要修改源对象定义即可为对象添加新的行为的方法,在JavaScript中,我们通过原型链也可以实现类似的效果,为对象添加新的行为。需要一定的Js原型链基础。

查看原文

WPF中创建一个矩形圆角动画

WPF 中内置了好几种动画,大多数场景可以坐到开箱即用,不过并没有内置 CornerRadiusAnimation ,本文将会介绍怎么实现一个 CornerRadiusAnimation 动画,实现 BorderCornerRadius 属性动画效果。

查看原文

WPF使用云母材质

在最新的Windows 11 OS中,微软为流畅设计(Fluent Design)带来了新的云母材质,云母材质一种不透明的动态效果,微软将其作为Windows 11应用窗体的默认材质。

查看原文