根据可观察到的变化动态更新 Angular 路线

问题描述 投票:0回答:1

我正在开发一个 Angular 应用程序,其中使用 Angular 路由。以下是我的 app-routing.module.ts 文件的片段:

// app-routing.module.ts:

import {
  NgModule
} from '@angular/core';
import {
  ActivatedRoute,
  Router,
  RouterModule,
  Routes
} from '@angular/router';
import {
  Observable,
  Subject,
  Subscription
} from 'rxjs';

const routes: Routes = [
  // ... adding my routes here.
];

@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule],
})
export class AppRoutingModule {

  constructor(
    private readonly router: RouterModule,
    schoolService: SchoolService
  ) {
    currentSchool$ = schoolService.currentSchool$;
    this.addWildCardRoutes();
  }
}

路由按预期工作。但是,我在 addWildCardRoutes() 函数中遇到问题。在此函数中,我的目标是订阅可观察的 currentSchool$ 并根据 currentSchool 的值动态添加通配符重定向路径,如下所示:

addWildCardRoutes(): void {
  this.currentSchoolSubscription = this.currentSchool$.subscribe(
    (currentSchool) => {
      if (currentSchool) {
        // remove existing wildcard routes:
        const index = routes.findIndex((route) => route.path === '**');
        if (index !== -1) {
          routes.splice(index, 1);
        }

        // add new wildcard route with current school name:
        routes.push({
          path: '**',
          redirectTo: `${currentSchool.name
              .replace(/ /gu, '-')
              .toLowerCase()}/home`,
        });
      } else {
        // add a default wildcard if there's no current school
        routes.push({
          path: '**',
          redirectTo: `default/home`,
        });
      }
      console.log(routes); // this console.log() works perfectly
      if (this.currentSchoolSubscription) {
        this.currentSchoolSubscription.unsubscribe();
      }
    }
  );
}

问题在于,即使订阅看起来工作正常(如控制台日志所证明),应用程序也无法识别更新的路由,并且永远不会添加新的通配符。看来路由必须是静态的,初始化后就不能更改了。

如何根据 currentSchool$ observable 的变化动态更新路线?

angular rxjs angular-routing angular-router rxjs-subscriptions
1个回答
0
投票

您的代码不起作用,因为您只改变了路由数组,而路由器不会以这种方式获取新配置。

您可以使用 Router#resetConfig 方法来更新路由器配置。

这是您的更新方法:

addWildCardRoutes(): void {
  this.currentSchool$
    .pipe(take(1)) // instead of manual unsubscribing
    .subscribe(
      (currentSchool) => {
        const newRoutes = currentSchool
          ? [
              ...routes.filter((route) => route.path !== '**'),
              {
                path: '**',
                redirectTo: `${currentSchool.name.replace(/ /gu, '-').toLowerCase()}/home`
              }
            ]
          : [
              ...routes,
              { path: '**', redirectTo: `default/home` }
            ];

        this.router.resetConfig(newRoutes);
      }
    );
}

请记住,它不会立即重定向用户,只是更改下一次导航的路线。


有很多实际用例可以做到这一点。根据用例,通常更容易使用可以根据服务中的某些数据进行重定向的Route Guard

在模块构造函数中包含此类代码也不是很常见,全局服务或 APP_INITIALIZER 可能是更好的选择,具体取决于用例。

© www.soinside.com 2019 - 2024. All rights reserved.