【问题标题】:Angular 13 router reuse routing not working after deploymentAngular 13路由器重用路由在部署后不起作用
【发布时间】:2022-08-23 04:21:23
【问题描述】:

我正在研究一种可以在本地正常工作的自定义路由器重用策略,但是当我将其部署到 Vercel 或 Netlify 等服务时,应用程序路由不起作用。我单击路由器链接更改页面,但页面组件未正确加载,除非我重新加载。

路由器重用策略在应用模块上提供

imports: [BrowserModule, AppRoutingModule],
providers: [
    { provide: RouteReuseStrategy, useClass: CustomRouteReuseStrategy },
  ],

应用路由:

const routes: Routes = [
  {
    path: \'\',
    pathMatch: \'full\',
    component: Page1Component,
  },
  {
    path: \'about\',
    component: Page2Component,
  },
  {
    path: \'test\',
    children: [
      { path: \'\', component: Page3Component, pathMatch: \'full\' },
      { path: \'page4\', component: Page4Component },
      { path: \'page4/:id\', component: Page4Component },
      { path: \':id\', component: Page3Component },
    ],
  },
  {
    path: \'**\',
    redirectTo: \'\',
  },
];

@NgModule({
  declarations: [],
  imports: [RouterModule.forRoot(routes, { onSameUrlNavigation: \'reload\' })],
  exports: [RouterModule],
})
export class AppRoutingModule {}

链接:

<a routerLink=\"/\">home</a>
<a routerLink=\"/about\">about</a>
<a routerLink=\"/test\">test</a>
<a routerLink=\"/test/page4\">page 4</a>

自定义路由器重用

export class CustomRouteReuseStrategy implements RouteReuseStrategy {
  private storedRoutes: { [key: string]: DetachedRouteHandle }[] = [];

  shouldDetach(route: ActivatedRouteSnapshot): boolean {
    return true;
  }

  store(route: ActivatedRouteSnapshot, handle: DetachedRouteHandle) {
    const path = route.routeConfig.component.name;
    const hasRoute = this.storedRoutes.some((i) => i[path]);
    if (handle && !hasRoute) {
      this.storedRoutes.push({ [path]: handle });
    }
  }

  shouldAttach(route: ActivatedRouteSnapshot): boolean {
    let path, isPathStored, remove;

    if (route.children && !route.routeConfig?.component) {
      return false;
    }

    path = route.routeConfig.component.name;

    if (this.storedRoutes.length > 1) {
      isPathStored = Object.keys(this.storedRoutes[0])[0] === path;
    }

    if (isPathStored) {
      remove = this.storedRoutes.pop();
    } else if (this.storedRoutes.length > 1) {
      remove = this.storedRoutes.shift();
    }

    if (remove) {
      this.deactivateOutlet(remove[Object.keys(remove)[0]]);
    }

    const hasRoute = this.storedRoutes.some((i) => i[path]);
    return !!route.routeConfig && hasRoute;
  }

  retrieve(route: ActivatedRouteSnapshot): DetachedRouteHandle | null {
    const path = route.routeConfig.component.name;
    const index = this.storedRoutes.findIndex((i) => i[path]);
    if (index > -1) {
      return this.storedRoutes[index][path];
    }

    return null;
  }

  shouldReuseRoute(
    future: ActivatedRouteSnapshot,
    curr: ActivatedRouteSnapshot
  ): boolean {
    return future.routeConfig === curr.routeConfig;
  }

  private deactivateOutlet(handle) {
    const componentRef: ComponentRef<any> = handle.componentRef;
    if (componentRef) {
      componentRef.destroy();
    }
  }
}

直播网址:https://angular-router-reuse.vercel.app/

    标签: angular


    【解决方案1】:

    正如this issue on GitHub 所评论的那样,Angular 在构建到生产环境后会更改组件的名称,因此组件名称不是唯一的,并且不能安全地用于比较。

    另一种以独特方式安全存储组件引用的方法是使用完整的路由路径,这对子路由是安全的。为了实现这一点,我们可以在 app.component based on this answer 上为路由器创建一个侦听器,它允许我们获取上一个和当前路由的值,但是要访问它,我们需要一个服务。

    考虑到这一点,自定义路由器重用类将如下所示:

    由于我们将使用构造函数,因此将需要可注入装饰器。

    @Injectable({
      providedIn: 'root',
    })
    export class CustomRouteReuseStrategy implements RouteReuseStrategy {
    

    然后我们可以导入我们的服务。

    constructor(private sessionService: SessionService) {}
    

    并使用完整的 previousRoute 作为 store 方法的参考名称。

    store(route: ActivatedRouteSnapshot, handle: DetachedRouteHandle) {
        const path = this.sessionService.previousRoute;
    

    以及 shouldAttach 和 retrieve 方法的完整 currentRoute。

    shouldAttach(route: ActivatedRouteSnapshot): boolean {
      const path = this.sessionService.currentRoute;
    

    .

    retrieve(route: ActivatedRouteSnapshot): DetachedRouteHandle | null {
        const path = this.sessionService.currentRoute;
    

    【讨论】:

      猜你喜欢
      • 2019-02-04
      • 2021-09-08
      • 2020-01-23
      • 1970-01-01
      • 2018-02-22
      • 2017-09-10
      • 2017-09-18
      • 1970-01-01
      • 2019-05-12
      相关资源
      最近更新 更多