2

我正在创建一个包含多个表单的页面,并且我想检测每个表单上的 mousedown、focus 和 blur 事件。

大多数时候,它们是同时发出的(例如,在已经选择另一个表单时单击一个表单,发出“blur”和“mousedown”)。目标是只处理其中一个。

我创建了一个名为interactions$ 的Observable,它发出的值是“事件”对象,例如mousedown、focus 或blur 事件。

我在那个 Observable 上使用管道,现在我有两个操作员选项:

  • debounceTime(100) 以便只处理最后一个
  • throttleTime(100) 以便只处理其中的第一个。
      this.interaction$
         .pipe(
            debounceTime(100),
            tap(evt => console.log('processing event' + evt))
         )
         .subscribe();

理想情况下,我希望在 blur 事件上同时处理 mousedown 和 focus 事件,但问题是当交互 $ 发出时:

  • “mousedown”在“blur”之前发出
  • 在“模糊”之后发出“焦点”

所以,我的问题是:

有没有办法根据源值应用 debounceTime() 或 throttleTime() ?

编辑:

此交互 $ 是一个主题,其值正在此事件处理程序上发出:

onFieldInteract(field: string, evt: Event) {
    this.interaction$.next(new FormFieldInteraction(field, evt.type));
}

其中 FormFieldInteraction 只是一个具有 2 个字符串属性的类。

编辑2:

基本上我想要这样的东西,但我不确定是否有任何 rxjs 运算符:

this.interaction$.pipe(
      // if event.type === 'blur',
      debounceTime(100),
      // else
      throttleTime(100),
      tap(evt => this.fieldInteract.emit(evt))
   ).subscribe();
4

1 回答 1

0

我认为我们需要更好地思考我们的问题。我认为这不仅仅是一个简单的运算符,而是问题需要更好的方法。

我分开了两种情况,一种是接收模糊和剩余事件。

  1. 看一下blur$,因为this.interaction$首先是去抖动然后过滤的整体结果是您将始终以这种方式获得正确的模糊事件。

  2. 至于remaining$,这里我们还有除模糊之外的其他事件,按照您的意愿进行节流。

最后,我们将它们合并在一起以获得您的预期行为。

看看更新的例子:

const blur$ = this.interaction$.pipe(
  debounceTime(100),
  filter((event) => event.type === 'blur'),
);

const remaining$ = this.interaction$.pipe(
  filter((event) => event.type !== 'blur'),
  throttleTime(100),
);

merge(blur$, remaining$)
  .pipe(tap((evt) => this.fieldInteract.emit(evt)))
  .subscribe();

您正在寻找这种行为吗?告诉我,我会根据您的实际需要修改答案。

于 2019-07-16T12:08:16.203 回答