在Angular中使用RxJS fromEvent操作符和输出事件发射器

13
假设有一个名为ChildComponent的组件,它会触发一个名为someEvent的事件。显然,我可以像这样在ParentComponent中声明并捕获该事件:<child-component (someEvent)="onSomeEvent($event)"></child-component>,并使用ParentComponent中的onSomeEvent方法处理它。但是我的目标是使用RxJS中的fromEvent操作符来处理该事件。我尝试了在使用@ViewChild获取ChildComponentElementRef后,使用fromEvent(this.childComponent.nativeElement, 'someEvent')。我发现以上方法仅在输出EventEmitter的事件名称与本机事件(如click)之一相同时有效,否则它不会响应/工作。是否有任何办法让fromEvent正常工作?

你为什么想要使用 fromEvent?你是想将 Angular 事件转换成可观察对象吗? - cartant
@cartant 实际上,使用 fromEvent 并不是必须的,但我正在尝试使用这种方式来处理 rxjs 操作符的流程。 - DongBin Kim
@cartant,您可以再发一遍您的回答吗?我有点困惑,它还是无法正常工作。 - DongBin Kim
1
我已经恢复了答案。在Angular中避免直接访问本机元素和不将事件发射器视为可观察对象有很好的理由。 - cartant
@cartant 我认为在Angular中直接访问本地元素并不太糟糕,除非我进行操作。为什么会有问题? - DongBin Kim
我觉得原始回答很有趣: 我发现如果输出 EventEmitter 的事件名称与诸如 click 之类的本机事件之一相同,则上述方法有效,但否则它无法正常工作。是否可以使用 fromEvent(..,'customClick') 来处理从 EventEmitter 触发的自定义事件?假设在同一个元素上有两个指令分别触发 customClick,并且第二个指令要监听此类事件,能行吗?我解决了注入一个指令到另一个指令并手动订阅 EventEmitter 的问题,但我很好奇为什么 fromEvent(..,'customClick') 无法正常工作。 - Felix
1个回答

15

如果您想将事件转换为可观察对象,您可以使用一个Subject,像这样:

@Component({
  selector: 'parent-component',
  template: `
    <child-component (someEvent)="subject.next($event)">
    </child-component>
  `
})
export class ParentComponent {
  public subject = new Subject<any>();
  constructor() {
    this.subject.pipe(
      tap(event => console.log(event)) // or whatever
    ).subscribe();
  }
}

这样做将为您提供一个可观察的源 - 主题 - 它会发出事件发射器所发出的任何值。从那里,您可以使用 RxJS 运算符组合任何您想要的内容。


那么除了使用Subject之外,就没有其他方式可以将Component事件(输出EventEmitter)与fromEvent操作符绑定了吗?根据您的建议,我可以按照自己的意愿使用rxjs操作符,但是为了实现我想要的功能,我似乎需要额外添加一个Subject变量。 - DongBin Kim
即使你能够这样做,也不应该。cartant的解决方案是你应该使用的正确方案。 - Ingo Bürk
@IngoBürk 显然,我可以直接订阅someEvent。为什么我还需要一个额外的 Subject? - DongBin Kim
2
@DongBinKim 因为 EventEmitter 不能保证被实现为可观察的对象。它作为可观察对象的行为是一种实现细节。 - cartant

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接