Angular 2.0, как обнаружить изменение маршрута в дочернем компоненте

Как я могу обнаружить изменение маршрута в дочернем компоненте? Это то, что я пробовал, но я вижу только компонент приложения, отслеживающий изменение маршрута. Я хочу иметь возможность определять, когда URL-адрес изменяется, например. #/meta/a/b/c в #/meta/a/b/c/d в компоненте MetaDetailView.

@RouteConfig([
    { path: '/', name: 'Home', redirectTo: ['Meta']},
    { path: '/meta/...', name: 'Meta', component: MetaMainComponent, useAsDefault: true},
    ...other routes...,
  ])    
export class AppComponent {
    constructor(private _router: Router) {
        _router.subscribe( (url) => console.log("app.url = " + url));
    }
}

@RouteConfig([
    { path: '/*other', name: 'Detail', component: MetaDetailViewComponent, useAsDefault: true},
])
export class MetaMainComponent {
    constructor(private _router: Router) {
        _router.subscribe( (url) => console.log("metamain.url = " + url));
        console.log("MetaMainComponent")
    }
}

export class MetaDetailViewComponent {
    constructor(private _router: Router) {
        _router.subscribe( (url) => console.log("metadetail.url = " + url));
        console.log("MetaDetailViewComponent")
    }
}

Спасибо, Джеспер.


person Jesper Kristiansen    schedule 22.03.2016    source источник


Ответы (3)


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

person Günter Zöchbauer    schedule 22.03.2016
comment
Это может сработать (попробую позже сегодня), но есть идеи, почему это не работает напрямую с Router? - person Jesper Kristiansen; 22.03.2016
comment
Я думаю, вы получаете правильный экземпляр Router только для компонентов, которые участвуют в маршрутизации. Что вы могли бы попробовать, так это _router.root.subscribe(...). - person Günter Zöchbauer; 22.03.2016
comment
Я смог заставить это работать только с помощью наблюдаемой глобальной службы, как было предложено. Все еще не понимаю, почему я не могу подписаться напрямую на маршрутизатор на дочернем компоненте. Я нашел эту статью о том, как добавить наблюдаемую службу. coryrylan.com/blog/angular-2-observable-data-services - person Jesper Kristiansen; 23.03.2016
comment
У вас нигде на компонентах нет ROUTER_PROVIDERS (только в bootstrap())? - person Günter Zöchbauer; 23.03.2016
comment
ага, только что перепроверил, дело только в загрузочной инъекции bootstrap(AppComponent, [ROUTER_PROVIDERS , LoggerService , provide(LocationStrategy, { useClass: HashLocationStrategy }) , RouteObserverService ]); - person Jesper Kristiansen; 24.03.2016

Решение RC3+:

constructor(private router: Router) {
  router.events.subscribe(event => {
    if (event.constructor.name === 'NavigationStart') {
      console.log(event.url);
    }
  });
}

Кроме того, вы можете отфильтровать событие NavigationStart, используя канал filter (RxJS 6+):

constructor(private router: Router) {
  router.events.pipe(
    filter(event => event instanceof NavigationStart),
  ).subscribe((event: NavigationStart) => {
    console.log(event.url);
  });
}
person dogpunk    schedule 28.09.2016
comment
this.router.events.subscribe(event => { if (event instanceof NavigationStart) { console.log(event.url); } }); не забудьте импортировать NavigationStart из angular/router - person Cabe Skuriles; 23.12.2016

У вас есть root-доступ с любого дочернего маршрутизатора:

_router.root.subscribe(route => console.log('route', route));
person igorzg    schedule 22.03.2016
comment
и как получить доступ к переменной _router - person Ravinder Payal; 20.05.2016
comment
@RavinderPayal вы должны внедрить в свой компонент, у которого есть определение RouteConfig. Вы можете ввести его в конструктор конструктора (private _router: Router), и после этого он будет доступен в любом месте вашего компонента через this._router - person igorzg; 20.05.2016
comment
да, я пробовал это, и из этого комментария я имею в виду, что переменная маршрутизатора больше не подлежит подписке - person Ravinder Payal; 21.05.2016
comment
Я попытался поместить этот слушатель в конструктор для моего файла AppComponent (тот же файл ts с моим определением начальной загрузки и RouteConfig), но я получаю эту ошибку во второй раз, когда я меняю URL-адрес: Ошибка: Uncaught (в обещании): ObjectUnsubscribedError Почему нам вообще нужен @RouteConfig([ ... ])? Я также попытался вызвать службу делегатов, чтобы поместить прослушиватель _router.root.subscriber(... listener), и я также получил ту же ошибку при второй загрузке URL-адреса. - person Benjamin McFerren; 22.05.2016
comment
это решение устарело? - person freethebees; 01.07.2016