在Angular2中订阅router.events.subscribe时,如何从Route或ActivatedRoute获取数据?
我试图在路由改变时从路由器获取数据,但没有成功。这里我设置了在Angular2中订阅router.events.subscribe时,如何从Route或ActivatedRoute获取数据?,angular,angular-ui-router,Angular,Angular Ui Router,我试图在路由改变时从路由器获取数据,但没有成功。这里我设置了asdf属性 @NgModule({ bootstrap: [AppComponent], declarations: [ AppComponent, LoginComponent, DashboardComponent, OverviewComponent, ], imports: [ BrowserModule, FormsModule, RouterModul
asdf
属性
@NgModule({
bootstrap: [AppComponent],
declarations: [
AppComponent,
LoginComponent,
DashboardComponent,
OverviewComponent,
],
imports: [
BrowserModule,
FormsModule,
RouterModule.forRoot([
{ path: '', pathMatch: 'full', redirectTo: '' },
{ component: LoginComponent, path: 'login' },
{
children: [
{ path: '', pathMatch: 'full', redirectTo: 'overview', data: { asdf: 'hello' } },
{ component: OverviewComponent, path: 'overview', data: { asdf: 'hello' } },
], component: DashboardComponent,
path: '',
},
]),
],
})
export class AppModule { }
在这里,当路由发生变化,但asdf
未定义时,我可以从路由器获取URL:(
如何获取asdf的值
编辑:我正在导航到
/overview
路由中的数据必须是一个对象数组,而不仅仅是一个对象,所以像这样定义它们
{ component: LoginComponent, path: 'login', data:[{myKey1: myValue1}] },
现在要检索它,请在组件构造函数中使用此代码
constructor(private router:Router, private activeRoute:ActivatedRoute) {
router.events
.filter(event => event instanceof NavigationEnd)
.map(_ => this.router.routerState.root)
.map(route => {
while (route.firstChild) route = route.firstChild;
return route;
})
.flatMap(route => route.data)
.subscribe(data => {
console.log(data[0].myKey1);
});
}
大概是这样的:
constructor(private router: Router,
private activatedRoute: ActivatedRoute)
{
this.router.events
.filter(event => event instanceof NavigationEnd)
.map(() => this.activatedRoute)
.map(route => route.firstChild)
.switchMap(route => route.data)
.map(data => data['asdf'])
}
this.router.events.pipe(
filter(event => event instanceof ActivationEnd),
map(event => (<ActivationEnd>event).snapshot),
map(snapshot => (<ActivatedRouteSnapshot>snapshot).data)).subscribe(data => {
console.log('data from the NEW route: ' + data);
});
以下内容已更新,可用于rxjs v6
constructor(private router: Router,
private activatedRoute: ActivatedRoute)
{
this.router.events
.pipe(
filter(event => event instanceof NavigationEnd),
map(() => this.activatedRoute),
map(route => route.firstChild),
switchMap(route => route.data),
map(data => data['asdf']))
}
下面是一个使用@Neelavar-example的修改示例 它可能看起来很长,但很简单,要有耐心,如果你坚持到底,它应该会起作用。只需按照概述的步骤进行操作就需要几分钟 我的设置的完整解释,为初学者 您应该已经知道如何创建组件和设置布线,我不会详细解释。 1.在Routes数组中设置数据属性 在您的routes数组中(您可以在app.module.ts或app routes.module.ts或在某些情况下在routes.ts文件中找到) 如果找不到,请在中检查基本路由设置:
export class RouteData {
title: string;
}
这只是为了添加类型以使用typescript中的observable,如果我稍后将其添加到数据类中,IDE可以为我自动完成“title”或“id”或“animation”
3.将以下内容导入app.component.ts
然后在构造函数的上方声明变量
routeData$: Observable<RouteData>;
4.然后再次在构造函数内部
根据@Tuizi示例注释改编的代码说明:
- 对于来自路由器的每个事件,仅过滤NavigationEnd事件(当路由器完成导航时)
- 然后映射(返回)当前激活的路由
- 将activatedRoute映射到第一个子级(路由器状态树中此路由的第一个子级)
- 然后switchMap会发出此路由的数据,使用switchMap因为发出的每个“数据”都是可观察的,所以当发出新的可观察数据时,switchMap会取消旧的可观察数据,从而节省内存
- 映射(返回)数据对象,为其指定RoutedData类型
- 最后,您可以在使用异步管道的模板中使用此可观察性
{{routeData.title}titlecase}
*注意:“async as”此时会中断模板中的类型检查:(
如果您第一次在浏览器中加载路由时点击该路由,则ActivateRoute将具有当前数据。但是,如果您随后单击导致第二个路由器导航的内容,则该第二个路由的ActivateRoute实例将具有原始路由的信息。这可能是因为它不是在将路由注入构造函数时,他激活了路由 但是,有一个已更新的ActivatedRouteSnapshot实例与ActivationEnd事件关联,因此您可以如下方式访问数据:
constructor(private router: Router,
private activatedRoute: ActivatedRoute)
{
this.router.events
.filter(event => event instanceof NavigationEnd)
.map(() => this.activatedRoute)
.map(route => route.firstChild)
.switchMap(route => route.data)
.map(data => data['asdf'])
}
this.router.events.pipe(
filter(event => event instanceof ActivationEnd),
map(event => (<ActivationEnd>event).snapshot),
map(snapshot => (<ActivatedRouteSnapshot>snapshot).data)).subscribe(data => {
console.log('data from the NEW route: ' + data);
});
this.router.events.pipe(
过滤器(事件=>ActivationEnd的事件实例),
映射(事件=>(事件).snapshot),
映射(快照=>(快照).data)).subscribe(数据=>{
log('来自新路由的数据:'+数据);
});
我认为这是一个已知的问题。您可以尝试使用setTimeout(()=>console.log(this.activatedRoute.snapshot.data['asdf'))
?不幸的是,它不起作用。今天有人建议使用Observable.zip()提出了类似的问题
与this.activatedRoute.snapshot.data
和this.router.events
。你是说这个吗?:正是……。这不是界面建议的:导出声明类型数据={[name:string]:any;}
@MildFuzz it dosent suggest other它的意思是Data
是数据的别名,它的类型是any
,也可以是数组。但是如果订阅router.events并检查类型,您会发现它是数组。如果您在子组件中使用数据,则此处的while循环有助于获取边缘r路由(数据所在的位置)。对于来自路由器的每个事件,我只过滤导航结束
事件,然后将此事件映射到激活的路由
(因为我想读取导航结束
上的激活的路由
的值)。我将激活的路由
映射到第一个孩子
(使用RouterModule.forRoot()声明的第一个子级然后制作一个switchMap
来获取这条路线的数据,一个switchMap,因为数据是可观察的。最后我将data
对象映射到我想要的键,在这种情况下,asdf
属性“filter”不存在于类型“可观察的”
可能是因为angular 6和rxjs 6的变化。你能发布upd吗ated代码?似乎不适用于惰性加载模块内的激活路由…第四步应在构造函数中完成,否则有可能
constructor(
private router: Router,
private activatedRoute: ActivatedRoute,
) {}
constructor(
private router: Router,
private activatedRoute: ActivatedRoute,
) {
this.routeData$ = router.events.pipe(
filter(routeEvent => routeEvent instanceof NavigationEnd),
map(() => activatedRoute),
map(activatedRoute => activatedRoute.firstChild),
switchMap(firstChild => firstChild.data),
map((data: RouteData) => data)
);
}
<span *ngIf="routeData$ | async as routeData">
{{ routeData.title | titlecase }}
</span>
this.router.events.pipe(
filter(event => event instanceof ActivationEnd),
map(event => (<ActivationEnd>event).snapshot),
map(snapshot => (<ActivatedRouteSnapshot>snapshot).data)).subscribe(data => {
console.log('data from the NEW route: ' + data);
});