如何在Angular2中订阅服务上的事件?

Per*_*eck 97 javascript angular

我知道如何使用EventEmitter引发事件.如果我有这样的组件,我还可以附加一个方法来调用:

<component-with-event (myevent)="mymethod($event)" />
Run Code Online (Sandbox Code Playgroud)

当我有这样的组件时,一切都很好.我将一些逻辑移动到服务中,我需要从服务内部引发一个事件.我做的是这样的:

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

  someMethodThatWillRaiseEvent() {
    this.myevent.next({data: 'fun'});
  }
}
Run Code Online (Sandbox Code Playgroud)

我有一个组件,需要根据此事件更新一些值,但我似乎无法使其工作.我试过的是这个:

//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
  }
}
Run Code Online (Sandbox Code Playgroud)

当引发它的服务不是一个组件时,我如何使MyComponent订阅该事件?

我在On 2.0.0-alpha.28上

编辑:修改我的"工作示例"实际工作,因此可以把重点放在不工作的部分;)

示例代码:http: //plnkr.co/edit/m1x62WoCHpKtx0uLNsIv

Mar*_*cok 121

更新:我找到了一个更好/正确的方法来使用BehaviorSubject或Observable而不是EventEmitter来解决这个问题.请参阅此答案:https://stackoverflow.com/a/35568924/215945

此外,Angular文档现在有一个使用Subjectcookbook示例.


原始/过时/错误答案:再次,不要在服务中使用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;
  }
}
Run Code Online (Sandbox Code Playgroud)

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);
  }
}
Run Code Online (Sandbox Code Playgroud)

Plunker

  • @asubanovsky,在[plunker](http://plnkr.co/edit/wzN7ZKU1CmVwbtxw8XFJ?p=preview)我只在引导程序(即根组件)级别注入NavService,因此应该只有一个服务实例对于整个应用程序.你在其他地方使用`providers:[NavService]`注入吗?如果是这样,您将获得该服务的多个实例. (5认同)

Run*_*boy 5

使用Alpha 28,我通过该eventEmitter.toRx().subscribe(..)方法以编程方式完成了对事件发射器的订阅。由于不直观,可能会在将来的版本中进行更改。

  • 不知道为什么它被否决了,它肯定有效。简而言之,要订阅事件发射器“ click”,请使用“ click.toRx()。subscribe(your_callback_function)”。 (2认同)