从this.router.events.subscribe()获取多个项目

时间:2017-07-27 20:50:33

标签: angular rxjs

我正在订阅路由器事件,以便在路线改变时更改我的页面标题,如此

this.routerSub$ = this.router.events
    .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((event) => {
        title = event['title']
            ? `${event['title']}`
            : 'Default Title'
        this.title.setTitle(title);
    });

我的问题是,在某些情况下,我想将标题设置为url中的值(路径的一部分)。我怎么在这里这样做?我知道我不能订阅网址和活动,但我很难搞清楚里面的内容。

以下是我正在尝试失败的内容

   this.router.events
        .filter(event => event instanceof NavigationEnd)
        .map(() => {
            return this.activatedRoute
        })
      .switchMap(route => {
        return route.data.combineLatest(route.url, (data, url) => {
            return data['title'] ? `Title: ${data['title']}` : url.join('');
        });
    })

在.switchMap行上,route是ActivatedRoute类型,route.data是Object类型,我在combineLatest()行上得到的错误是

  

route.data.combineLatest不是函数

1 个答案:

答案 0 :(得分:0)

如果我们将角度路由详细信息放在一边,您基本上想要组合来自两个不同流的值。至少有几种方法可以做到这一点。

案例1 。您希望在任何一个流发出并使用两者中的最新值时更新标题。

使用combineLatest



const getTitle$ = (activatedRoute) => {
    return activatedRoute.url
        .combineLatest(activatedRoute.data, (url, data) => {
            return url + data;
        });
};

const url = Rx.Observable.interval(400).take(3).map(x => `url_${x} `);
const data = Rx.Observable.interval(200).take(6).map(x => `data_${x}`);

getTitle$({ url, data }).subscribe(title => console.log(title));

<script src="https://unpkg.com/@reactivex/rxjs@5.0.3/dist/global/Rx.js"></script>
&#13;
&#13;
&#13;

案例2 。您只想在url流发布时更新标题,还要从data流中获取最新值。

使用withLatestFrom

&#13;
&#13;
const getTitle$ = (activatedRoute) => {
    return activatedRoute.url
        .withLatestFrom(activatedRoute.data, (url, data) => {
            return url + data;
        });
}

const url = Rx.Observable.interval(400).take(3).map(x => `url_${x} `);
const data = Rx.Observable.interval(200).take(6).map(x => `data_${x}`);

getTitle$({ url, data }).subscribe(title => console.log(title));
&#13;
<script src="https://unpkg.com/@reactivex/rxjs@5.0.3/dist/global/Rx.js"></script>
&#13;
&#13;
&#13;

如果您遇到您的observable不包含任何这些运算符,请尝试显式导入它们:

import 'rxjs/add/operator/combineLatest';
import 'rxjs/add/operator/withLatestFrom';

<强>更新

为了使其更具体,这里是一个更接近原始示例的代码示例:

this.router.events
    .filter(event => event instanceof NavigationEnd)
    ... // <- route mapping and filtering skipped for brevity
    .switchMap(route => {
        return route.data.combineLatest(route.url, (data, url) => {
            // make the title out of data and url
            return data['title'] ? `Title: ${data['title']}` : url.join('');
        });
    })
    .subscribe(title => this.title.setTitle(title));