我不能在单个元素上多次收听一个事件.

我注意到以下几点:

  • 仅当从生命周期方法(如ngAfterViewCheckedngDoCheck或新的afterRender()挂钩)触发可观察到的RxJS时,才会出现此问题.
  • 当收听不同的事件clickamp;mousedown时,没有问题
  • 这可能与zone.js打补丁有关,因为提供ɵNoopNgZone没有问题.

我真的不明白发生了什么事.有什么 idea 吗?

转载:

export class App implements AfterViewChecked {
  @ViewChild("button") button!: ElementRef<HTMLElement>;
  render$$ = new Subject<void>();

  ngAfterViewInit() {
    this.render$$
      .pipe(switchMap(() => fromEvent(this.button.nativeElement, "click")))
      .subscribe(() => console.log("--- click 1 ---"));
    this.render$$
      .pipe(switchMap(() => fromEvent(this.button.nativeElement, "click")))
      .subscribe(() => console.log("--- click 2 ---"));
  }

  ngAfterViewChecked() {
    this.render$$.next();
  }
}

Stackblitz repro

在该示例中,尽管监听相同的事件/按钮,但从不记录--- click 2 ---.

推荐答案

这是"意料之中的",我已经找到了为什么会这样:

Angel在Angular 区域中判断其事件侦听器,并且每个单独的NgZone.run调用都会触发更改检测.因此,呈现$$主题发出,导致SwitchMap取消订阅仍处于挂起状态的事件侦听器,从而有效地取消该事件.

这个问题可以通过打开事件合并来避免,这样只在调用了所有事件侦听器之后才运行更改检测.

因此,解决办法是:

bootstrapApplication(
  App,
  {
    providers: [provideZoneChangeDetection({ eventCoalescing: true })],
  }
);

Angular相关问答推荐

无法绑定到ngIf,因为它不是dis angular 17的已知属性

Angular :将动态创建的零部件附加为目标元素的子项

如何在Angular 17 SSR中处理Swiper 11 Web组件事件

无效的ICU消息.缺少';}';|Angular material 拖放(&A)

选中/取消选中-复选框未正确返回TRUE或FALSE

Ng serve不工作,没有错误或消息来显示问题所在

阶段JS画布覆盖 bootstrap 模式

当快速拖动光标时会丢失元素 - Angular

在Angular中扩展多个类

如何在运行Angular应用程序的容器中访问Docker容器?

Nz 树 Select .如何在子 node 中显示父 node 名称?

找不到模块'webpack'

在同一个组件中使用 MatSort 的多个 mat-table

等待多个promises完成

在Angular2的 Select 列表中设置最初 Select 的项目

未绑定断点 - VS Code | Chrome | Angular

如何使用 Angular 6 工作的 ngModel 创建自定义输入组件?

Angular 2 Material 2 日期 Select 器日期格式

Angular 应用程序必须在新部署后清除缓存

Angular2:将数组转换为 Observable