Angular 向任何组件报告当前路由和参数?
Angular report current route and params to any component?
我真的不知道为什么这这么难......为什么我们正式不应该关心路由组件内部以外的任何地方的路由......但是:
我正在尝试为我的header(和任何其他组件)编写一个服务,它可以知道当前的路由和参数。也很高兴知道当前加载的组件,但这不太重要。
我尝试了 this thread 的各种解决方案,最接近我的是 RoyiNamir 的释义,但正如您从附带的 stackblitz 中看到的那样,它只报告页面加载时的参数,而不是随后的尽管有订阅和 NavigationEnd 的存在,但导航(尽管在解释路由事件和 rxjs 方面我是公认的超级绿色)。
我也不确定如何在返回的 object 中传递当前路由以及参数。
代码:
import {Injectable} from '@angular/core';
import {ActivatedRoute, NavigationEnd, Router} from "@angular/router";
import {Observable} from "rxjs";
import {first, filter, map, switchMap} from "rxjs/operators";
@Injectable({providedIn: 'root'})
export class RouteService {
constructor(
private route: ActivatedRoute,
private router: Router
){}
public getActivatedRouteParameter(): Observable<any>
{
let params
params = this.router.events.pipe(
filter(e => e instanceof NavigationEnd),
map((): ActivatedRoute => {
let route = this.route;
while (route.firstChild)
{
route = route.firstChild;
}
return route;
}),
filter((route: ActivatedRoute) => route.outlet === 'primary'),
switchMap((route: ActivatedRoute) => route.paramMap) , first()
);
return params;
}
}
如果你像这样修改 getActivatedRouteParameter
似乎工作正常:
public getActivatedRouteParameter(): Observable<any>
{
let params
params = this.router.events.pipe(
filter(e => e instanceof NavigationEnd),
map((): ActivatedRoute => {
let route = this.route;
while (route.firstChild)
{
route = route.firstChild;
}
return route;
}),
filter((route: ActivatedRoute) => route.outlet === 'primary'),
switchMap((route: ActivatedRoute) => route.paramMap.pipe(first())) , /* first() */
tap(console.log)
);
return params;
}
在 switchMap
的 first()
外部 添加它会导致 整个流 在第一次发射后完成,这将是一个空对象(因为 ActivatedRoute
's properties are BehaviorSubjects
):
function createActivatedRoute(c: ActivatedRouteSnapshot) {
return new ActivatedRoute(
new BehaviorSubject(c.url), new BehaviorSubject(c.params), new BehaviorSubject(c.queryParams),
new BehaviorSubject(c.fragment), new BehaviorSubject(c.data), c.outlet, c.component, c);
}
通过将 first()
添加到 switchMap
的内部可观察对象,您不会得到重复项。否则你会得到重复的,因为在你的情况下,每个路由导航都将 使用相同的组件 (HomeComponent
),这意味着它不会被破坏,所以 ActivatedRoute
将是相同的,它的可观察属性也是如此。
这也意味着内部 observable 不会完成,所以当 ActivatedRoute
被重用时,它会 update its BehaviorSubject
instances.
...
if (!shallowEqual(currentSnapshot.params, nextSnapshot.params)) {
(<any>route.params).next(nextSnapshot.params);
}
...
这发生在管道的早期,在 NavigationEnd
事件之前。
我真的不知道为什么这这么难......为什么我们正式不应该关心路由组件内部以外的任何地方的路由......但是:
我正在尝试为我的header(和任何其他组件)编写一个服务,它可以知道当前的路由和参数。也很高兴知道当前加载的组件,但这不太重要。
我尝试了 this thread 的各种解决方案,最接近我的是 RoyiNamir 的释义,但正如您从附带的 stackblitz 中看到的那样,它只报告页面加载时的参数,而不是随后的尽管有订阅和 NavigationEnd 的存在,但导航(尽管在解释路由事件和 rxjs 方面我是公认的超级绿色)。
我也不确定如何在返回的 object 中传递当前路由以及参数。
代码:
import {Injectable} from '@angular/core';
import {ActivatedRoute, NavigationEnd, Router} from "@angular/router";
import {Observable} from "rxjs";
import {first, filter, map, switchMap} from "rxjs/operators";
@Injectable({providedIn: 'root'})
export class RouteService {
constructor(
private route: ActivatedRoute,
private router: Router
){}
public getActivatedRouteParameter(): Observable<any>
{
let params
params = this.router.events.pipe(
filter(e => e instanceof NavigationEnd),
map((): ActivatedRoute => {
let route = this.route;
while (route.firstChild)
{
route = route.firstChild;
}
return route;
}),
filter((route: ActivatedRoute) => route.outlet === 'primary'),
switchMap((route: ActivatedRoute) => route.paramMap) , first()
);
return params;
}
}
如果你像这样修改 getActivatedRouteParameter
似乎工作正常:
public getActivatedRouteParameter(): Observable<any>
{
let params
params = this.router.events.pipe(
filter(e => e instanceof NavigationEnd),
map((): ActivatedRoute => {
let route = this.route;
while (route.firstChild)
{
route = route.firstChild;
}
return route;
}),
filter((route: ActivatedRoute) => route.outlet === 'primary'),
switchMap((route: ActivatedRoute) => route.paramMap.pipe(first())) , /* first() */
tap(console.log)
);
return params;
}
在 switchMap
的 first()
外部 添加它会导致 整个流 在第一次发射后完成,这将是一个空对象(因为 ActivatedRoute
's properties are BehaviorSubjects
):
function createActivatedRoute(c: ActivatedRouteSnapshot) {
return new ActivatedRoute(
new BehaviorSubject(c.url), new BehaviorSubject(c.params), new BehaviorSubject(c.queryParams),
new BehaviorSubject(c.fragment), new BehaviorSubject(c.data), c.outlet, c.component, c);
}
通过将 first()
添加到 switchMap
的内部可观察对象,您不会得到重复项。否则你会得到重复的,因为在你的情况下,每个路由导航都将 使用相同的组件 (HomeComponent
),这意味着它不会被破坏,所以 ActivatedRoute
将是相同的,它的可观察属性也是如此。
这也意味着内部 observable 不会完成,所以当 ActivatedRoute
被重用时,它会 update its BehaviorSubject
instances.
...
if (!shallowEqual(currentSnapshot.params, nextSnapshot.params)) {
(<any>route.params).next(nextSnapshot.params);
}
...
这发生在管道的早期,在 NavigationEnd
事件之前。