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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/31131490/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 06:17:25  来源:igfitidea点击:

How to subscribe to an event on a service in Angular2?

javascriptangular

提问by Per Hornsh?j-Schierbeck

I know how to raise an event with the EventEmitter. I can also attach a method to be called if I have a component like this:

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

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

When I have a component like this, everything works great. I moved some logic into a service and I need to raise an event from inside the Service. What I did was this:

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

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

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

I have a component that needs to update some value based on this event but i can't seem to make it work. What I tried was this:

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

//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
  }
}

How do i make MyComponent subscribe to the event when the service that raises it is not a component?

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

I'm on On 2.0.0-alpha.28

我在 2.0.0-alpha.28

EDIT: Modified my "working example" to actually work, so focus can be put on the not-working part ;)

编辑:修改我的“工作示例”以使其实际工作,因此可以将重点放在不工作的部分;)

Example code: http://plnkr.co/edit/m1x62WoCHpKtx0uLNsIv

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

回答by Mark Rajcok

Update: I have found a better/proper way to solve this problem using a BehaviorSubject or an Observable rather than an EventEmitter. Please see this answer: https://stackoverflow.com/a/35568924/215945

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

Also, the Angular docs now have a cookbook example that uses a Subject.

此外,Angular 文档现在有一个使用 Subject食谱示例



Original/outdated/wrong answer:again, don't use an EventEmitter in a service. That is an anti-pattern.

原始/过时/错误答案:同样,不要在 service 中使用 EventEmitter。那是一种反模式。

Using beta.1... NavService contains the EventEmiter. Component Navigation emits events via the service, and component ObservingComponent subscribes to the events.

使用 beta.1... NavService 包含 EventEmiter。组件导航通过服务发出事件,组件 ObservingComponent 订阅事件。

nav.service.ts

导航服务.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

组件.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

Plunker

回答by Runeboy

Using alpha 28, I accomplished programmatically subscribing to event emitters by way of the eventEmitter.toRx().subscribe(..)method. As it is not intuitive, it may perhaps change in a future release.

使用 alpha 28,我通过该eventEmitter.toRx().subscribe(..)方法以编程方式订阅了事件发射器。由于它不直观,它可能会在未来的版本中改变。