在 Angular 的 header 组件中显示路由标题,始终返回未定义

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

我有一个看似简单的问题。我有一个标题组件,我想在其中显示当前活动路线的标题。为此,我将 ActivatedRoute 注入标题组件中,并尝试显示路由标题,如下所示:

export class HeaderComponent {
    public title$;

    constructor(private route: ActivatedRoute) {
        this.title$ = route.title;
    }
}

以及组件的html

<header>
    <h1>My Website - {{ title$ | async }}</h1>
</header>

不知怎的,这不起作用。但我可以看到我在不同路由中定义的标题会更新浏览器窗口标题。

angular observable
1个回答
0
投票

您的标头组件似乎在您的 ShellComponent 中使用,我想您的路由配置感觉如下所示:

const routes: Route[] = [
  {
    path: '',  
    component: ShellComponent, // <-- Header component is used here
    children: [  // might be load children
       { path: 'route1', title: 'My title', component: ...}, // <-- title is here
       ...
    ] 
  }
]

因此,如果这是正确的,那么您可以看到 Header 组件位于定义了标题的路由上方的路由/注入器/组件树中。

当您在 HeaderComponent 中注入 ActivatedRoute 时,您将获得此包装器的路由实例

{
    path: '',  
    component: ShellComponent,

它没有标题,所以你会得到它

undefined

您可以做的是,如果您没有多路由器出口结构,那么您可以手动深入路由树以获取最多子路由。像这样的东西

  constructor(private route: ActivatedRoute) {}

  get leaf(): ActivatedRoute {
    let leaf = this.route;
    while (leaf.firstChild) {
      leaf = leaf.firstChild;
    }
    return leaf;
  }

并在模板中执行

{{leaf.title | async}}

您应该小心组件上的变更检测策略。

每当更改检测到此组件时,您的

get leaf()
就会被执行,但如果您有
OnPush
,您将必须标记您的组件,以便在手动更改路由时进行检查。例如,您可以监听 router.events,每当有
NavigationEnd
事件时,执行
markForCheck
来更新它。

或者你可以做一个混合版本以使其与 OnPush 一起使用

  #route = inject(ActivatedRoute);
  #router = inject(Router);

  title$ = this.#router.events.pipe(
    filter((evt) => evt instanceof NavigationEnd),
    startWith(null),
    switchMap(() => this.leaf.title)
  );

  get leaf(): ActivatedRoute {
    let leaf = this.#route;
    while (leaf.firstChild) {
      leaf = leaf.firstChild;
    }
    return leaf;
  }

并在模板中使用

{{title$ | async}}

所以最终的解决方案取决于您的变更检测策略设置

工作结果:https://stackblitz.com/edit/stackblitz-starters-ca3d4z?file=src%2Fmain.ts

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