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

Как подписаться на событие в службе в Angular2?

Я знаю, как поднять событие с помощью EventEmitter. Я также могу приложить метод для вызова, если у меня есть такой компонент:

<component-with-event (myevent)="mymethod($event)" />

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

export class MyService {
  myevent: EventEmitter = new EventEmitter();

  someMethodThatWillRaiseEvent() {
    this.myevent.next({data: 'fun'});
  }
}

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

//Annotations...
export class MyComponent {
  constructor(myService: MyService) {
    //myService is injected properly and i already use methods/shared data on this.
    myService.myevent.on(... // 'on' is not a method <-- not working
    myService.myevent.subscribe(.. // subscribe is not a method <-- not working
  }
}

Как заставить MyComponent подписаться на событие, когда служба, которая его повышает, не является компонентом?

Я вкл. 2.0.0-alpha.28

EDIT: изменил мой "рабочий пример", чтобы фактически работать, поэтому фокус может быть помещен в нерабочую часть;)

Пример кода: http://plnkr.co/edit/m1x62WoCHpKtx0uLNsIv

4b9b3361

Ответ 1

Обновление. Я нашел лучший/правильный способ решить эту проблему, используя BehaviorSubject или Observable, а не EventEmitter. См. Этот ответ: fooobar.com/questions/39863/...

Кроме того, в документах Angular теперь есть пример поваренной книги, в котором используется тема.


Исходный/устаревший/неправильный ответ: снова, не использовать EventEmitter в службе. Это анти-шаблон.

Использование beta.1... NavService содержит EventEmiter. Компонент Навигация выдает события через службу, а компонент ObservingComponent подписывается на события.

nav.service.ts

import {EventEmitter} from 'angular2/core';
export class NavService {
  navchange: EventEmitter<number> = new EventEmitter();
  constructor() {}
  emitNavChangeEvent(number) {
    this.navchange.emit(number);
  }
  getNavChangeEmitter() {
    return this.navchange;
  }
}

components.ts

import {Component} from 'angular2/core';
import {NavService} from '../services/NavService';

@Component({
  selector: 'obs-comp',
  template: `obs component, item: {{item}}`
})
export class ObservingComponent {
  item: number = 0;
  subscription: any;
  constructor(private navService:NavService) {}
  ngOnInit() {
    this.subscription = this.navService.getNavChangeEmitter()
      .subscribe(item => this.selectedNavItem(item));
  }
  selectedNavItem(item: number) {
    this.item = item;
  }
  ngOnDestroy() {
    this.subscription.unsubscribe();
  }
}

@Component({
  selector: 'my-nav',
  template:`
    <div class="nav-item" (click)="selectedNavItem(1)">nav 1 (click me)</div>
    <div class="nav-item" (click)="selectedNavItem(2)">nav 2 (click me)</div>
  `,
})
export class Navigation {
  item = 1;
  constructor(private navService:NavService) {}
  selectedNavItem(item: number) {
    console.log('selected nav item ' + item);
    this.navService.emitNavChangeEvent(item);
  }
}

Plunker

Ответ 2

Используя альфа 28, я выполнил программную подписку на излучатели событий с помощью метода eventEmitter.toRx().subscribe(..). Поскольку это не интуитивно, возможно, это может измениться в будущей версии.