我正在从一个组件路由到另一个组件。路线完成后,我想使用上一条路线的URL。我已将下面的代码放入要路由到的组件的构造函数中,但它不会在第一个路径上触发。在第一个路径之后,该功能每次都会触发。
this.router.events
.filter(e => e instanceof NavigationEnd)
.pairwise().subscribe((e) => {
console.log(e);
});
如果我删除成对功能,它似乎在第一条路线上触发,但它只列出当前路线,而不是前一路线。
router.events
.filter(e => e instanceof NavigationEnd)
.subscribe(e => {
console.log(e);
});
我的目标是在新组件路由到时检索先前的路由。我在这做错了什么?
我有完全相同的情况,我发现it's too late在子组件的构造函数中使用pairwise订阅NavigationEnd。
您可以订阅根组件中的路由器,并通过服务共享路由数据,如下例所示:
events.service.ts
import { Injectable } from '@angular/core';
import { RouteChanged } from '../models/route-changed.model';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
@Injectable()
export class EventsService {
public routeChanged = new BehaviorSubject<RouteChanged>({ prevRoute: '/', currentRoute: '/' });
constructor() {
}
}
app.component.ts(你的根组件)
...
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit, OnDestroy {
private subscriptions = new Subscription();
constructor(private eventsService: EventsService) {
this.subscriptions.add(this.router.events
.filter(event => event instanceof NavigationEnd)
.pairwise()
.subscribe(navigationEvents => {
const prevPage = <NavigationEnd>navigationEvents[0];
const currentPage = <NavigationEnd>navigationEvents[1];
this.eventsService.routeChanged.next(
{ prevRoute: prevPage.urlAfterRedirects, currentRoute: currentPage.urlAfterRedirects });
}));
}
ngOnDestroy(): void {
this.subscriptions.unsubscribe();
}
...
}
你的目标,route.ts
...
constructor(private eventsService: EventsService) {
this.subscriptions.add(this.eventsService.routeChanged.subscribe((routeChanged) => {
// use routeChanged.prevRoute and routeChanged.currentRoute here...
}));
}
附:在服务中使用BehaviorSubject或ReplaySubject非常重要,以便在页面加载后子组件订阅时获取正确的先前路由事件。
答案已经给出:当组件为其注册时,已经引发了NavigationEnd事件。我不喜欢“Dimitar Tachev”的想法,通过在主题中代理这些事件来创建一种解决方法。在我的情况下,解决方案是:
最后,另一种解决方案是将订阅路由更改事件移动到组件的构造函数中。
原因是导航事件发生时您的组件尚不存在。
创建一个注入app.component.ts
的全局服务,并将其注入您的组件。
在服务上创建'helper'可观察对象。
// RouterEventsService.ts
navigationStart$ = this.router.events.pipe(filter((e): e is NavigationStart => e instanceof NavigationStart));
navigationEnd$ = this.router.events.pipe(filter((e): e is NavigationEnd => e instanceof NavigationEnd));
navigationEndReplay$ = this.navigationEnd$.pipe(shareReplay(1));
在服务的构造函数中,您必须只订阅navigationEndReplay$
事件。这意味着稍后在您的组件中,您可以订阅它并获取缓存的最新结束事件。
// RouterEventsService.ts constructor
this.routerEvents.navigationEndReplay$.subscribe(); // note: unsubscribe in app.component not needed
然后你可以在你的组件中使用routerEvents.navigationEndReplay$
,它会在组件初始化后立即触发。你可以在你的构造函数,ngOnInit
,ngAfterContentInit
等中使用它。
最好保持navigationEnd$
和navigationEndReplay$
明确。
pairwise
排放第二次和随后的排放(http://reactivex.io/rxjs/class/es6/Observable.js~Observable.html#instance-method-pairwise)
所以设置初始值很重要,例如:
this.router.events
.startWith(new NavigationEnd(0, '/', '/'))
.filter(e => e instanceof NavigationEnd)
.pairwise()
.subscribe((e) => {
console.log(e);
});
我只是偶然发现了相同的问题,并找到了原因:订阅路由器事件的服务从未由依赖注入器实例化,因为服务未在该路由注入。
服务似乎只是在某个地方注入时才会被实施。
因此,如果调用了整个代码(而不是事件),请检查您的第一条路线。