我正在使用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模板之前,一个组件如何将其渲染任务委托给另一组件?我不能在这里使用重定向,因为那样会再次重新引发路由问题。
请随时询问我的目的。谢谢。
答案 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应用中浏览,直到硬刷新重新初始化应用为止。