Angular - 在应用组件中获取路由数据
Angular - Get Route data in app component
我在app-routing.module.ts
中配置了以下路由
const routes: Routes = [
{
path: 'abc/:id', component: AbcComponent, data: { category: 'Public' }
},
{
path: 'xyz/:id/tester/:mapId', component: XyzComponent, data: { category: 'Private' }
},
{ path: '**', redirectTo: '/page-not-found', pathMatch: 'full'}
]
在app.component.ts
中,我想根据URL传递的每条路线的类别:
例如:去 http://myapp.com/abc/123
应该 return 分类为 Public
去 http://myapp.com/xyz/123/tester/456
应该 return 分类为 Private
这是我目前的情况:
constructor(
private activatedRoute: ActivatedRoute,
private router: Router
)
{
checkRouteAndGetCategory()
}
checkRouteAndGetCategory()
{
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 =>
console.log('data', data)
)
}
上面的代码好像没有得到正确的路由。例如:如果我在 http://myapp.com/abc/123
页面并导航到 http://myapp.com/xyz/123/tester/456
,它似乎获取了 http://myapp.com/abc/123
页面的数据。
这是我的应用程序组件中的内容
constructor(private route: ActivatedRoute) {
}
ngOnInit(): void {
this.router.events.pipe(
filter(event => event instanceof NavigationEnd),
map(() => this.rootRoute(this.route)),
filter((route: ActivatedRoute) => route.outlet === 'primary'),
mergeMap((route: ActivatedRoute) => route.data)
).subscribe((event: {[name: string]: any}) => {
this.titleService.setRouteTitle(event['title']);
});
}
private rootRoute(route: ActivatedRoute): ActivatedRoute {
while (route.firstChild) {
route = route.firstChild;
}
return route;
}
我的应用程序路线如下:
{ path: 'login', component: LoginComponent, data: { title: 'Login' } }
而我的标题服务负责设置标题。
我看到我的和你的唯一区别是你在构造函数中绑定到路由器,而我在 ngOnInit
中绑定。您可以尝试调用 ngOnInit
中的内容吗?我不确定这是否会有所作为,但值得一试。
在组件中获取路由数据的捷径
constructor(router:Router, route:ActivatedRoute) {
router.events
.filter(e => e instanceof NavigationEnd)
.forEach(e => {
this.title = route.root.firstChild.snapshot.data.category;
});
}
我会考虑将其转移到服务中,比如 CategoryService
类别服务
import { Injectable } from '@angular/core';
import { ActivatedRoute, NavigationEnd, Router } from '@angular/router';
import { filter, map, mergeMap } from 'rxjs/operators';
@Injectable({
providedIn: 'root'
})
export class CategoryService {
constructor(private router: Router ) { }
private routerEvents = this.router.events;
private navigationEndEvent = this.routerEvents
.pipe(filter(event => event instanceof NavigationEnd))
category$ = this.navigationEndEvent
.pipe(
mergeMap(() => this.rootRoute(this.router.routerState.root).data),
map(({category}: any) => category)
)
private rootRoute = (route: ActivatedRoute): ActivatedRoute => {
return route.firstChild ? this.rootRoute(route.firstChild) : route;
}
}
组件
constructor(private categoryService: CategoryService) {
}
category$ = this.categoryService.category$;
...
}
HTML
<span>{{ category$ | async }}</span>
我在app-routing.module.ts
const routes: Routes = [
{
path: 'abc/:id', component: AbcComponent, data: { category: 'Public' }
},
{
path: 'xyz/:id/tester/:mapId', component: XyzComponent, data: { category: 'Private' }
},
{ path: '**', redirectTo: '/page-not-found', pathMatch: 'full'}
]
在app.component.ts
中,我想根据URL传递的每条路线的类别:
例如:去 http://myapp.com/abc/123
应该 return 分类为 Public
去 http://myapp.com/xyz/123/tester/456
应该 return 分类为 Private
这是我目前的情况:
constructor(
private activatedRoute: ActivatedRoute,
private router: Router
)
{
checkRouteAndGetCategory()
}
checkRouteAndGetCategory()
{
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 =>
console.log('data', data)
)
}
上面的代码好像没有得到正确的路由。例如:如果我在 http://myapp.com/abc/123
页面并导航到 http://myapp.com/xyz/123/tester/456
,它似乎获取了 http://myapp.com/abc/123
页面的数据。
这是我的应用程序组件中的内容
constructor(private route: ActivatedRoute) {
}
ngOnInit(): void {
this.router.events.pipe(
filter(event => event instanceof NavigationEnd),
map(() => this.rootRoute(this.route)),
filter((route: ActivatedRoute) => route.outlet === 'primary'),
mergeMap((route: ActivatedRoute) => route.data)
).subscribe((event: {[name: string]: any}) => {
this.titleService.setRouteTitle(event['title']);
});
}
private rootRoute(route: ActivatedRoute): ActivatedRoute {
while (route.firstChild) {
route = route.firstChild;
}
return route;
}
我的应用程序路线如下:
{ path: 'login', component: LoginComponent, data: { title: 'Login' } }
而我的标题服务负责设置标题。
我看到我的和你的唯一区别是你在构造函数中绑定到路由器,而我在 ngOnInit
中绑定。您可以尝试调用 ngOnInit
中的内容吗?我不确定这是否会有所作为,但值得一试。
在组件中获取路由数据的捷径
constructor(router:Router, route:ActivatedRoute) {
router.events
.filter(e => e instanceof NavigationEnd)
.forEach(e => {
this.title = route.root.firstChild.snapshot.data.category;
});
}
我会考虑将其转移到服务中,比如 CategoryService
类别服务
import { Injectable } from '@angular/core';
import { ActivatedRoute, NavigationEnd, Router } from '@angular/router';
import { filter, map, mergeMap } from 'rxjs/operators';
@Injectable({
providedIn: 'root'
})
export class CategoryService {
constructor(private router: Router ) { }
private routerEvents = this.router.events;
private navigationEndEvent = this.routerEvents
.pipe(filter(event => event instanceof NavigationEnd))
category$ = this.navigationEndEvent
.pipe(
mergeMap(() => this.rootRoute(this.router.routerState.root).data),
map(({category}: any) => category)
)
private rootRoute = (route: ActivatedRoute): ActivatedRoute => {
return route.firstChild ? this.rootRoute(route.firstChild) : route;
}
}
组件
constructor(private categoryService: CategoryService) {
}
category$ = this.categoryService.category$;
...
}
HTML
<span>{{ category$ | async }}</span>