如何将具有某些 id 的路由重定向到人类友好的 url 并处理 angular 路由中的规范 url?

How to redirect the route with some id to human friendly url and handle canonical url in angular routes?

我有两个url格式

example.com/posts/:postIdexample.com/posts/:postId/:postTitle就像stack-overflow个人问题url一样。

在angular路由中,我需要将所有带有:postId的url重定向到:postId/:PostTitle,或者直接加载带有:postId/:PostTitle的页面到相同的页。

post.module.ts

const routes: Routes = [
    {
        path: ':postId',
        resolve: {data: PdResolver}, 
        redirectTo: ':postId/:PostTitle', 
        pathMatch: 'full'
    },
    {
        path: ':postId/:PostTitle',
        component: PostComponent,
        data: {
            title: 'This has to be the post fetched title'
        }
    }
];

I don't have the title so first I need to get postTitle using the postId, so we have a post data resolver (PdResolver),

问题更新:解决方法:

我尝试使用 child 组件,它至少解决了这个问题,但仍然想知道这是否是我应该遵循的方法。

    {
        path: ':postId',
        component: PostOutletComponent,
        resolve: {data: PdResolver},
        children: [
            {
                path: ':postTitle',
                component: PostComponent,
            }]

    }

PostOutletComponent 中,我在获取标题后进一步导航到 child 组件

PostOutletComponent.ts

static stripHtml(html: string) {
        let div = document.createElement('DIV');
        div.innerHTML = html;
        const cleanText = div.innerText;
        div = null;
        return cleanText;
    }

 ngOnInit() {
        this.reolveData = this._route.snapshot.data;
        let postTitle = PostOutletComponent.stripHtml(
            this.reolveData.data.data.post_title);
        postTitle = postTitle.replace(/\s+/g, '-').toLowerCase();
        this.router.navigate([postTitle], {relativeTo: this._route});
    }

我根据你的代码做了一个 Stackblitz:https://stackblitz.com/edit/angular-r1tvx2

它解决了如果用户导航到具有现有 ID 但标题错误的 URL 时出现的问题。在上面的示例中,标题被更正为 Stack Overflow。

我只使用了一个解析器和一个组件 class。解析器负责重定向到正确的 URL。请注意,Resolver 放置在具有标题的更具体的路由中。

路由配置,路由的顺序很重要,先到标题更具体的路由:

  {
    path: "posts/:id/:title",
    component: PostComponent,
    resolve: { somedata: PostDetailResolverService }
  },
  {
    path: "posts/:id",
    redirectTo: "posts/:id/title-to-be-repalced",
  },
  { path: "**", component: PageNotFoundComponent }
];

解析器,重定向到具有正确标题的 URL:

  resolve(
    route: ActivatedRouteSnapshot,
    state: RouterStateSnapshot
  ): Observable<Somedata> | Observable<never> {
    let id = +route.paramMap.get("id");
    let title = route.paramMap.get("title");
    return this.getData(id).pipe(
      take(1),
      mergeMap(res => {
        if (res) {
          console.log("Resolver - Navigation continues to the route with data:", res);
          if (!title || title != res.title) {
            this.router.navigate(["posts/" + res.id + "/" + res.title]);
          } 
          return of(res);
        } else {
          // id not found
          console.log("Navigation cancelled");
          this.router.navigate([""]);
          return EMPTY;
        }
      })
    );
  }