Angular 2 Как получить данные, переданные маршрутизатором в событии изменения

#angular #angular2-routing

#angular #angular2-маршрутизация

Вопрос:

Ниже приведен пример моего маршрута { path: 'calendar', component: CalendarComponent, canActivate: [CanActivateViaAuthGuard], data: { title: 'Calendar' } },

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

 this._router.events
.filter(event => event instanceof RoutesRecognized)
.subscribe((event: any) => {})
  

Я могу получить данные следующим образом,

event.state._root.children[0].value._routeConfig.data

Я считаю, что это неправильный способ получения данных. Какой правильный способ получить данные здесь?


В принципе, я хочу задать заголовок страницы, поэтому, когда я нахожусь на странице календаря, в заголовке моей HTML-страницы должно быть ‘Calendar’. Я не хочу, чтобы этот код выполнялся на каждой странице. Итак, я создаю общий компонент, который может получать данные с каждого маршрута и изменять заголовок страницы.

Редактировать

Я всегда могу получить данные в самом компоненте, но это было бы избыточно. Мне придется кодировать в каждом компоненте, чтобы задать заголовок. Я хочу, чтобы это упражнение выполнялось в одном месте, поэтому я избегаю в компоненте.

Комментарии:

1. просто как идея: вы можете использовать resolve атрибут в маршрутизаторе, чтобы создать распознаватель, который выполняет работу с заголовком. Но вы должны добавить этот атрибут к каждому маршруту. Или вы используете canActivate -атрибут для своего маршрута, чтобы задать заголовок и просто вернуть true для маршрутов angular.io/docs/ts/latest/guide/router.html #!#разрешить-защита

Ответ №1:

Вы можете отправлять данные в качестве аргумента в пути. Тогда ваш маршрут выглядит следующим образом:

 { path: 'calendar/:title', component: CalendarComponent }
  

В компоненте календаря вы можете подписаться на этот параметр следующим образом

 ngOnInit() {
  this.route.params.subscribe(params => {
    var title = params['title'];
    ...
  });
}
  

Ваша функция будет вызываться изначально и каждый раз при изменении параметра.

Комментарии:

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

2. Хорошо, возможно, я не совсем понимаю, что вы делаете. Откуда вы получаете title ? Если вы загружаете это с сервера или имеете в своем компоненте приложения, вы можете просто включить это в шаблон вашего компонента приложения и видеть это везде.

3. Это статические данные, я хочу задать заголовок страницы, поэтому, когда я нахожусь на странице календаря, в заголовке моей HTML-страницы должно быть ‘Calendar’. Я не хочу, чтобы этот код выполнялся на каждой странице. Итак, я создаю общий компонент, который может получать данные с каждого маршрута и изменять заголовок страницы.

Ответ №2:

Для Angular 4

если вы хотите получить доступ к пользовательским данным маршрута в дочерних компонентах или компонентах более низкого уровня, для которых вы определили пользовательские данные маршрута, вы можете сделать следующее в этом компоненте, учитывая, что вы передаете пользовательские данные маршрута data: {title: 'somedata'} :

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

Но, если вы хотите получить доступ к пользовательским данным маршрута глобально из родительского компонента или компонента верхнего уровня, чтобы получить доступ к изменению пользовательских данных маршрута, тогда вы должны прослушивать события маршрутизатора, в частности, RoutesRecognized или NavigationEnd events. Я собираюсь показать две процедуры с 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 amp;amp; 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);
});
  

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