角度服务中的 EventEmitter 或 RxJS 主题

Posted

技术标签:

【中文标题】角度服务中的 EventEmitter 或 RxJS 主题【英文标题】:EventEmitter or RxJS Subject in angular service 【发布时间】:2018-02-10 04:56:01 【问题描述】:
    EventEmitter 是 RxJS Observable 吗? 在 Angular 文档中,它解释了如何从 使用 EventEmitter 的子组件到父组件。我们应该使用 EventEmitter 只能在组件中使用,也可以用于 Angular 服务 也?

    在 Angular 文档中,它解释了父母和孩子如何通过共享服务进行通信,该服务使用 可观察的 RxJS 主题。我们可以使用 EventEmitter 代替 RxJS 此 MissionService 示例中的主题?如果我们可以在服务中使用 EventEmitter,请帮助使用 EventEmitter 转换此示例。我是 Angular 新手。

    https://angular.io/guide/component-interaction#parent-and-children-communicate-via-a-service

看了这些相关的帖子后,我有点困惑:

Delegation: EventEmitter or Observable in Angular2 Global Events in Angular 2 What is the proper use of an EventEmitter? Angular 2 Service + RxJS BehaviorSubject or EventEmitter Shared RxJS subject for bidirectional data binding in Angular 2

【问题讨论】:

Angular 2 Event emitters vs Subject的可能重复 【参考方案1】:

EventEmiter 扩展自 RxJs 主题,您可以将其用作 Observable。

Angular sources

    export declare class EventEmitter<T> extends Subject<T> 
      __isAsync: boolean;
      constructor(isAsync?: boolean);
      emit(value?: T): void;
      subscribe(generatorOrNext?: any, error?: any, complete?: any): any;
    

在父子组件之间共享数据的最佳实践是使用@Input 和@Output

当您需要使用服务进行共享时。您需要使用 Subject 或 BehaviorSubject

服务示例

@Injectable()
export class MyService 
  private data: BehaviorSubject<MyData> = new BehaviorSubject(null);

  getData(): Observable<MyData> 
    return this.data;
  

  setData(d: MyData): void 
    this.data.next(d);
  

在组件中使用

data: Observable<MyData>;

constructor(private myService: MyService) 

ngOnInit() 
   this.data = this.myService.getData();

在模板中使用

<div>data|async</div>

【讨论】:

最好不要在服务设置中使用 rxjs(包括队列)或变量作为全局状态(在 ngModel 而不是组件上初始化)。全局状态是一种反模式/反mvvm/mvc。【参考方案2】:

有许多不同的方式来处理事件场景。

EventEmitter 是将子事件传递给父事件的最常用方式。假设您创建了一个子组件并在那里单击了一个按钮,您可能希望在父组件中单击 clicked 事件:

&lt;button (click)="clickEmitter.emit()"&gt;button&lt;/button&gt;

<child-component (clickEmitter)="buttonClicked()"></child-component>

共享服务(可注入)可用于存储多个组件的数据。

Subject 和 BehaviorSubject 可用于在组件之间共享事件(有时通过共享服务)。例如:我使用了一个带有用户 BehaviorSubject 的 authService 来获取每个组件中的登录用户对象。

这些只是许多其他用例中的一些简单示例。

【讨论】:

是的。 rxjs 不必通过服务来完成。通常最好避免存储状态,包括服务上的 rxjs 消息队列。有时在服务上是一个很好的呼吁。 如果不指定component.ts代码,html代码并没有真正的用处。命名输入/输出的良好做法是:@Input() public name: string; @Output() public nameChange = new EventEmitter(); (其中 data 是父组件上的公共字段)用于双向绑定。如果您需要其他方法,它只是 的快捷方式

以上是关于角度服务中的 EventEmitter 或 RxJS 主题的主要内容,如果未能解决你的问题,请参考以下文章

text RxJ使运营商扁平化

如何正确删除节点 js eventemitter 中的事件侦听器

子组件无法通过服务订阅 EventEmitter

EventEmitter 的正确用途是啥?

nodejs Websocket服务器 - 检测到可能的EventEmitter内存泄漏

JavaScript中的高阶函数并在EventEmitter的类中引用'this'关键字[重复]