Как получить текущие пользовательские данные маршрута в angular 2?

Я установил маршруты, как показано ниже

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

  }
}

Ответ 1

  public constructor(private route:ActivatedRoute, private router:Router) {
      console.log(route.snapshot.data['title']);
  }

Ответ 2

Для 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);
});

Примечание.. Хотя последний из них короче и обычно работает, но если у вас есть вложенные маршруты, рекомендуется использовать первый.

Ответ 3

После того, как я проверил различные решения, ответ группы угловой поддержки фактически решил эту проблему.

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);
      }
    });
  }
}

Ответ 4

его работа для компонента, который не перемещается (например, заголовок):

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 к этому ответу

Ответ 5

Ответ 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);
          });

Ответ 6

Для тех, кто сейчас использует 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;
      });
  }

Ответ 7

Это сработало для меня в 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);
        }

    }

Ответ 8

если вы хотите иметь текущие данные маршрута, можете получить их из ActivatedRoute

public constructor(private activatedRoute:ActivatedRoute) {
    console.log((activatedRoute.data as any).value);
}

Ответ 9

Вы можете подписаться на 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);
    });
}