Ответ 1
public constructor(private route:ActivatedRoute, private router:Router) {
console.log(route.snapshot.data['title']);
}
Я установил маршруты, как показано ниже
const appRoutes: Routes = [
{
path: 'login',
component: LoginComponent,
data: {
title: 'Login TTX'
}
},
{
path: 'list',
component: ListingComponent,
data: {
title: ' TTX Home Page',
module:'list'
}
},
{
path: '',
redirectTo: '/login',
pathMatch: 'full'
},
];
теперь, когда я прихожу к '/list'
маршруту, а затем 'listing.component.ts'
, я написал ниже код
export class ListingComponent {
public constructor(private router:Router) {
//here how i can get **data** of **list** routes
}
}
public constructor(private route:ActivatedRoute, private router:Router) {
console.log(route.snapshot.data['title']);
}
Для Angular 4 +
Если вы поместите следующий код в компоненты родителя или верхнего уровня, такие как AppComponent
, тогда это не сработает. Он работает только на дочерних или более низкоуровневых компонентах, для которых вы определили пользовательские данные маршрута:
public constructor(private route:ActivatedRoute, private router:Router) {
console.log(route.snapshot.data['title']);
}
Итак, если вы хотите получить доступ к пользовательским данным маршрута глобально от компонента родителя или верхнего уровня, чтобы получить доступ к изменению пользовательских данных маршрута, вы должны прослушивать события маршрутизатора, особенно события RoutesRecognized
или NavigationEnd
. Я собираюсь показать две процедуры с AppComponent
двумя событиями:
Первый подход:
export class AppComponent implements OnInit, AfterViewInit {
constructor(private activatedRoute: ActivatedRoute, private router: Router) { }
ngOnInit() {
this.router
.events
.filter(event => event instanceof NavigationEnd)
.map(() => {
let child = this.activatedRoute.firstChild;
while (child) {
if (child.firstChild) {
child = child.firstChild;
} else if (child.snapshot.data && child.snapshot.data['custom_data']) {
return child.snapshot.data['custom_data'];
} else {
return null;
}
}
return null;
}).subscribe( (customData: any) => {
console.log(customData);
});
}
}
Второй подход использует:
this.router.events
.filter(event => event instanceof RoutesRecognized)
.map( (event: RoutesRecognized) => {
return event.state.root.firstChild.data['custom_data'];
})
.subscribe(customData => {
console.log(customData);
});
Примечание.. Хотя последний из них короче и обычно работает, но если у вас есть вложенные маршруты, рекомендуется использовать первый.
После того, как я проверил различные решения, ответ группы угловой поддержки фактически решил эту проблему.
ActivatedRoute не переносит данные, и здесь решение для определения переменной страницы в data: { page: 'login' }
.
import { Router, RoutesRecognized } from '@angular/router';
export class AppComponent {
page = '';
constructor(private router: Router) {
// listen to page variable from router events
router.events.subscribe(event => {
if (event instanceof RoutesRecognized) {
let route = event.state.root.firstChild;
this.page = 'page-' + route.data.page || '';
console.log('Page', this.page);
}
});
}
}
его работа для компонента, который не перемещается (например, заголовок):
this.route.root.firstChild.snapshot.data['title']
и полный пример:
import { Component, OnInit } from '@angular/core';
import { ActivatedRoute, Router, NavigationEnd } from '@angular/router';
export class HeaderComponent implements OnInit {
title: string;
constructor(private route: ActivatedRoute, private router: Router ) { }
ngOnInit() {
this.router.events.subscribe(event => {
if(event instanceof NavigationEnd) {
this.title = this.route.root.firstChild.snapshot.data['title']
}
});
}
}
Cerdit к этому ответу
Ответ asmmahmud работает до Angular 5.x, но 6.X ломает this.router.events
так как в rxjs 6.x есть критические изменения. Так что просто наткнулся на обновление:
import {filter} from 'rxjs/operators';
import {map, mergeMap} from 'rxjs/internal/operators';
router.events
.pipe(filter(event => event instanceof NavigationEnd),
map(() => {
let route = activatedRoute.firstChild;
let child = route;
while (child) {
if (child.firstChild) {
child = child.firstChild;
route = child;
} else {
child = null;
}
}
return route;
}),
mergeMap(route => route.data)
)
.subscribe(data => {
console.log(data);
});
Для тех, кто сейчас использует Angular 6+ и последнюю версию RXJS 6, вот что основано на вышеприведенных ансерах:
Пример маршрутизации:
const routes: Routes = [
{path: 'home', component: HomeComponent, data: {title: 'Home'}},
// {path: '', redirectTo: 'home', pathMatch: 'full'},
{path: 'login', component: LoginComponent, data: {title: 'Login'}},
{path: 'dashboard', component: DashboardComponent, data: {title: 'Dashboard'}, canActivate: [AppAuthGuard]},
{path: 'eventDetails', component: EventCardComponent, data: {title: 'Details'}},
{path: '**', redirectTo: 'home', pathMatch: 'full'},
];
Как получить заголовок примера:
ngOnInit() {
this.routerEventSubscription = this.router.events
.pipe(filter(event => event instanceof RoutesRecognized))
.pipe(map((event: RoutesRecognized) => {
return event.state.root.firstChild.data['title'];
})).subscribe(title => {
this.title = title;
});
}
Это сработало для меня в app.component.ts(ng 5)
constructor(
private router: Router,
) {
router.events.subscribe((routerEvent: Event) => {
this.checkRouterEvent(routerEvent);
});
}
checkRouterEvent(routerEvent: Event): void {
if (routerEvent instanceof ActivationStart) {
if (routerEvent.snapshot.data.custom_data) {
this.currentpage = routerEvent.snapshot.data['custom_data'];
console.log('4.' + this.currentpage);
}
}
если вы хотите иметь текущие данные маршрута, можете получить их из ActivatedRoute
public constructor(private activatedRoute:ActivatedRoute) {
console.log((activatedRoute.data as any).value);
}
Вы можете подписаться на ActivatedRoute.data. Это как-то похоже на ответ от @dinesh-kumar, но я полагаю (activatedRoute.data as any).value
activRoute.data (activatedRoute.data as any).value
- это хак, использующий тот факт, что activatedRoute.data
реализован как BehaviorSubject. Но ActivatedRoute.data выставляется как Observable<Data>
, поэтому правильным способом будет подписка (не забудьте отписаться, или take(1)
и т.д.) Или использовать async
канал и т.д.
constructor(private route: ActivatedRoute) {
this.route.data.subscribe((data) => {
console.log(data);
});
}