简体   繁体   English

router.events 在 Angular 6 中无法与异步一起正常工作

[英]router.events doesn't work properly with async in Angular 6

I'm using this code to dynamic title我正在使用此代码动态标题

this.router.events.pipe(
    filter(event => event instanceof NavigationEnd),
    map(() => this.activatedRoute),
    map(route => {
        while (route.firstChild) {
            route = route.firstChild;
        }
        return route;
    }),
    filter(route => route.outlet === "primary"),
    mergeMap(route => route.data)
).subscribe(data => this.title = data.title || "");

and view: {{title}}并查看: {{title}}

I wanted to refactor this part (to have async instead subscribe ) So I did:我想重构这部分(用async代替subscribe )所以我做了:

this.title = this.router.events.pipe(
    filter(event => event instanceof NavigationEn
    mapTo(this.activatedRoute),
    map(route => {
        while (route.firstChild) {
            route = route.firstChild;
        }
        return route;
    }),
    filter(route => route.outlet === "primary"),
    mergeMap(route => route.data),
    pluck("title")
);

and view: {{title | async}}并查看: {{title | async}} {{title | async}}

But when I open page via URL, or even refresh the page then title is null.但是当我通过 URL 打开页面,甚至刷新页面时, title为空。 It works only when I navigate directly on page (by menu, buttons etc).它仅在我直接在页面上导航(通过菜单、按钮等)时才有效。

I don't know why it was working properly with subscribe and it doesn't with async .我不知道为什么它可以与subscribe一起正常工作,而它不能与async

I was even trying only with log, but it's the same issue, title is not appearing at the beginning.我什至只尝试使用日志,但这是同样的问题,标题没有出现在开头。

this.title = this.router.events.pipe(
    tap(() => console.log("test"));
)

I ran into the same issue in angular 7 - ie wanting to use async (rather than subscribe ) with this.router.events.pipe .我在 angular 7 中遇到了同样的问题 - 即想要在this.router.events.pipe使用async (而不是subscribe )。

I solved it using startWith ( https://www.learnrxjs.io/operators/combination/startwith.html ) so I could capture the initial loading event as well as NavigationEnd events.我使用startWith ( https://www.learnrxjs.io/operators/combination/startwith.html ) 解决了它,因此我可以捕获初始加载事件以及NavigationEnd事件。

Here's the relevant code fragment:这是相关的代码片段:

  this.router.events.pipe(
    startWith('Initial load'),
    filter(event => event === 'Initial load' || event instanceof NavigationEnd),
    // rest of code here
  );

This sounds like a race condition.这听起来像是一种竞争条件。 The template doesn't always get a chance to subscribe before the router events have completed.在路由器事件完成之前,模板并不总是有机会订阅。 You might be able to handle this by replaying the router events so new subscribers (like the async directive) receive events that they may have missed.您可以通过重播路由器事件来处理此问题,以便新订阅者(如async指令)接收他们可能错过的事件。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM