Подтвердить что ты не робот

Angular 2 - Как прослушивать событие без шаблона?

Проблема

Обычно в Angular 2 можно прослушивать событие через следующий синтаксис:

<my-elem (customEvent)="customEventProcessor"></my-elem>

Но когда я использую маршрутизатор, этот хост - <my-elem> - не существует ни в одном шаблоне. Вместо этого есть <router-outlet>, и мой компонент загружается при навигации. Таким образом, суть моей проблемы заключается в том, как заставить мой хост прослушивать мое пользовательское событие, не полагаясь на шаблон?

Дополнительные сведения

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

<list-view (customEvent)="customEventProcessor()"></list-view>

Только для полноты компонент list-view, который испускает событие, также имеет предсказуемую структуру:

<button (click)="onDetailsClick(propertyOfInterest)">Click here</button>

list-view отправляет событие до родителя через наблюдение.

class ListView {

    ...

        public onDetailsClick(property: string): void {

            this.customEvent.next({ value: property });

        }

}

и это событие вызывает функцию customEventProcessor(). Все идет нормально. Однако, когда я использую маршрутизатор для управления присутствием list-view, я не могу (насколько мне известно) вставить команду для мониторинга какого-либо события.

Я не уверен, как лучше всего подходит этот случай.

4b9b3361

Ответ 1

Эта проблема еще не решена (см. этот вопрос github). Вот одно из возможных решений на данный момент (см. этот плунжер):

@Component({
  selector: 'my-app',
  directives: [RouterOutlet, RouterLink],
  template: `
    <h1>{{ message }}</h1>
    <a [router-link]="['./MyElem1']">MyElem1</a>
    <a [router-link]="['./MyElem2']">MyElem2</a>
    <router-outlet></router-outlet>
  `
})
@RouteConfig([
  { path: '/', redirectTo: '/my-elem1' },
  { path: '/my-elem1', name: 'MyElem1', component: MyElem1 },
  { path: '/my-elem2', name: 'MyElem2', component: MyElem2 },
])
export class App {
  message: string = 'Click on the button';

  @ViewChild(MyElem1) myElem1: MyElem1;
  @ViewChild(MyElem2) myElem2: MyElem2;

  constructor(router: Router) {
    let subs = null;
    router.subscribe(() => {
      if (subs) { subs.unsubscribe(); subs = null; }

      if (this.myElem1) {
        subs = this.myElem1.customEvent1.subscribe(m=>this.processCustomEvent(m));
      }
      if (this.myElem2) {
        subs = this.myElem2.customEvent2.subscribe(m=>this.processCustomEvent(m));
      }
    });
  }

  processCustomEvent(message) { this.message = message }
}