基于服务结果的动态路径

时间:2019-10-19 16:07:53

标签: angular routing

我正在使用Angular 8创建WordPress主题。

我想允许用户从WP仪表板中选择一个自定义的永久链接结构。

注意:这不是WP问题。我只是向熟悉它的人提到WP,以便他们能够更好地理解该问题。对于不熟悉它的人,永久链接结构基本上是一组规则,用于显示带有友好URL的WP内容。

如果用户可以选择自定义的永久链接结构,那么我必须为angular应用设置动态路由设计,以使其正常工作。

因此,可以称为 customRoutesSvc 的服务(是否真的需要服务?)将连接到数据库并获取配置,如下所示:

{
 "posts_permalink":"\/%postname%\/",
 "tag_base":"tag",
 "category_base":"category"
}

假设 customRoutesSvc 现在具有这些值作为属性。

因此,我需要以某种方式提供我的路由模块,以考虑该信息。

我的路由模块使用延迟加载,并且具有固定的路由路径。

{
  path: 'category/:category',
  loadChildren: () => import('./view-category/view-category.module').then(m => m.ViewCategoryModule)
},
{
  path: 'tag/:tag',
  loadChildren: () => import('./view-tag/view-tag.module').then(m => m.ViewTagModule)
},
{
  path: 'post/:slug',
  loadChildren: () => import('./view-post/view-post.module').then(m => m.ViewPostModule)
}

我在想类似的东西:

{
  path: customRoutesSvc.category_base + 'category/:category',
  loadChildren: () => import('./view-category/view-category.module').then(m => m.ViewCategoryModule)
},
{
  path: customRoutesSvc.tag_base + '/:tag',
  loadChildren: () => import('./view-tag/view-tag.module').then(m => m.ViewTagModule)
},
{
  path: '**',
  loadChildren: () => import('./view-post/view-post.module').then(m => m.ViewPostModule)
}

请注意,最后一条路线将吸收所有东西,然后view-post模块将处理其余部分并显示帖子或重定向到错误页面。

我为什么对此有疑问?

据我了解,Angular在服务之前加载Angular模块。不是因为任何偏好,而是因为服务是捆绑到Angular模块中的ES2015模块。这意味着:Angular需要其Angular模块才能知道要加载哪些ES2015模块(组件,服务,管道等)。因此,Angular路由模块是在服务之前加载的,因此服务无法与模块本身进行通信。

到目前为止,我尝试了什么?

我试图思考并得到答案。

请不要解释我在这里询问代码。这更多是一个概念性问题,其目的不是针对代码答案,而是针对理论答案,这将帮助我保持独立。

我认为唯一可行的解​​决方案是什么?

由于该服务无法与路由模块对话(是真的吗?),因此我需要使用吸收所有内容的单个路径(**)进行父路由。

然后,我需要有一个DispatchComponent,它将分析该URL并将其与有关永久链接结构的现有信息进行比较。

最后,我需要DispatchComponent将内容重定向到正确的最终组件,这将负责提供结果。

如果这是解决方案,那么如何在延迟加载中实现这一目标?在Angular实际渲染HTML模板之前,一个组件如何将其渲染任务委托给另一组件?我不能在这里使用重定向,因为那样会再次重新引发路由问题。

请随时询问我的目的。谢谢。

1 个答案:

答案 0 :(得分:1)

我认为您正在寻找的是动态路由。这是一个文档不足的可悲的功能,但是您实际上可以在运行时修改路由器的配置,例如,在订阅中获取customRoutesSvc的数据库配置:

  constructor(private router: Router) {
    router.resetConfig({
      // A new routes object like the one you supply in the routing module.
    });
    // It's also possible to manipulate the config object directly.
    router.config.unshift({ path: 'page1', component: Page1Component });
  }

因此,您认为服务无法与路由器对话的假设是错误的。您可能拥有一条包含解析器的所有路由,该解析器可获取数据库配置,重置路由器配置并根据新配置将路由器重新导航到相同位置。

路由模块路由:

const routes: Routes = [
  { path: '**', component: DummyComponent, resolve: {routing: RoutingResolve}}
];

路由解析器:

import { Injectable } from '@angular/core';
import { Router, ActivatedRouteSnapshot, RouterStateSnapshot, Resolve} from '@angular/router';

@Injectable()
export class RoutingResolve implements Resolve<any> {

  constructor(private router: Router, private routes: customRoutesSvc ) {}

  resolve(
    route: ActivatedRouteSnapshot,
    state: RouterStateSnapshot
  ): Observable<any>|any {
    let config = this.routes.getRoutingStructure();
    this.router.resetConfig(config);
    this.router.navigate(route.url);
  }
}

由于现在配置已被替换为其他配置,因此无所不包,并且我们自由地在Angular应用中浏览,直到硬刷新重新初始化应用为止。