Angular ActivatedRoute 数据返回一个空对象

我用一些数据登记了一条路线:

const routes: Routes =
[
{path: 'my-route', data: { title: 'MyTitle' }, component: MyComponent},
];

我正试着用 ActivatedRoute访问路线数据:

import { Component, OnInit } from '@angular/core';
import { ActivatedRoute } from '@angular/router';


@Component({...})
export class MyComponent implements OnInit {
private routeData;


constructor(private route: ActivatedRoute) {}


ngOnInit() {
this.routeData = this.route.data.subscribe((data) => {
console.log(data); // this is returning an empty object {}
});
}
}

但由于某些原因,data是一个空对象。

如何解决这个问题?

43773 次浏览

Edit: the problem is that I was trying to access the ActivatedRoute from a Component which is outside the <router-outlet>. So it looks like that this is the intended behaviour.

However I still think that my answer below can be useful to anyone who is trying to accomplish the same thing.


I found a workaround on GitHub (thanks manklu) that I used in order to accomplish what I needed:

import { Component, OnInit } from '@angular/core';
import { Router, RoutesRecognized } from '@angular/router';


@Component({...})
export class MyComponent implements OnInit {
private routeData;


constructor(private router: Router) { }


ngOnInit() {
this.router.events.subscribe((data) => {
if (data instanceof RoutesRecognized) {
this.routeData = data.state.root.firstChild.data;
}
});
}
}

doing this way this.routeData will hold the route data that I needed (in my case the page title).

Below should work:

constructor(private route: ActivatedRoute) {}


ngOnInit() {
console.log(this.route.snapshot.data);
}

I Don't know the version spoken, but as of Angular 6, this worked for me:

(Ofcourse thanks to shinDath)

  routeData;
ngOnInit() {
//child route param doesnt go up to parent route params.
this.router.events.subscribe((val) => {
if (val instanceof ActivationEnd) {
if(!$.isEmptyObject(val.snapshot.params)){
this.routeData = val.snapshot.params;
}
}
});
}

This is part of my code (NOTE: I'm using Angular 8):

constructor(private _router: Router, private _route: ActivatedRoute) {}


ngOnInit() {
...
this.listenRouting();
}


listenRouting() {
this._router.events.subscribe((router: any) => {
routerUrl = router.url;
if (routerUrl && typeof routerUrl === 'string') {
routerList = routerUrl.slice(1).split('/');
console.log("data.breadcrumbs", this._route.snapshot.routeConfig.children.find(child => child.path === routerList[routerList.length - 1]).data.breadcrumbs);
...
}
});
}

So data is "hiding" under ActivatedRoute.snapshot.routeConfig.children Array. Each child contains, among other things, data. In my case data is configured in routing.module, e.g.:

const routes: Routes = [
{ path: "facility-datas",
component: FacilityTerminal,
data: {
breadcrumbs: "b ft"
}
},
...
];
import { AfterViewInit, Component} from '@angular/core';
import { ActivatedRoute } from '@angular/router';




@Component({
selector: 'app-users',
templateUrl: './users.component.html',
styleUrls: ['./users.component.scss']
})
export class UsersComponent implements AfterViewInit {
paramId: string;


constructor(private activatedRoute: ActivatedRoute) {}


ngAfterViewInit(): void {
this.paramId = this.activatedRoute.snapshot.params.id;
console.log('paramId =', this.paramId);
}


}

Get route custom data for component outside <router-outlet> (Angular 8):

constructor(private router: Router) {}
    

ngOnInit() {
this.router.events.subscribe(data => {
if (data instanceof ActivationStart) {
console.log(`Custom data`, data.snapshot.data);
}
});
}

Answer from Angular contributor, link

this.router.events.pipe(
filter((e) => e instanceof NavigationEnd),
map(() => {
let route = this.activatedRoute;


while (route.firstChild) {
route = route.firstChild;
}


return route;
}),
filter((route) => route.outlet === 'primary'),
mergeMap((route) => route.data),
tap(console.log)
);


constructor(
private router: Router,
private activatedRoute: ActivatedRoute,
) {}