angular - 基于服务结果的动态路径
问题描述
我正在使用 Angular 8 创建一个 WordPress 主题。
我想允许用户从 WP Dashboard 中选择一个自定义的永久链接结构。
注意:这不是 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 模板之前将其渲染任务委托给另一个组件?我不能在这里使用重定向,因为那只会再次重新启动路由问题。
请随时要求对我的目的进行说明。谢谢你。
解决方案
我认为您正在寻找的是动态路由。这是一个可悲的未充分记录的功能,但您实际上可以在运行时修改路由器的配置,例如在获取您的数据库配置的订阅中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 应用程序中自由导航,直到硬刷新重新初始化应用程序。
推荐阅读
- c++ - 浮点运算何时“无效”?
- vue.js - 将 .env 变量导入 Vuetify variables.scss
- r - 在箱线图中实现定义的值
- php - 在 XML 响应 php 中解析 JSON
- google-bigquery - 在 bigquery 的同一列上应用不同的条件
- java - spring boot 编译找不到符号componentscan
- unity3d - Unity中的浮动原点和视觉效果图
- gitlab-ci - gitlab ci:作业工件的“没有要上传的文件”
- python - 我的 Scrapy 脚本非常慢,在 3 分钟内提取 100 个项目
- python - 手动触发 dag 后气流调度程序不起作用