如何在同一控件上为不同事件实现不同的debounceTime?

时间:2019-07-16 13:16:03

标签: javascript angular rxjs primeng

我有一个从FormBuilder构建的控件。 我想为每个按键设置一个debounceTime,而不是在用户失去控件焦点时放置。

this._control.valueChanges
    .pipe(
      takeUntil(this.ngUnsubscribe),
      debounceTime(1000),
      distinctUntilChanged()
    )
    .subscribe((value) => {
      // Logic goes here
    });

-------------------------------
onInputChange(event: any): void {

  console.log(this.autoComplete.focus, "1"); // Return true

  setTimeout(() => console.log(this.autoComplete.focus, "2")); // return false

}

因此第一个控制台日志为true,而具有setTimeout的为false

将去抖动时间设置为1000,这是很有意义的,因此它可以防止多次调用后端服务,但这在lostFocus事件的情况下是没有意义的。

我可能在这里错过了一些东西,但是

如何在同一控件上为不同事件实现不同的debounceTime?

2 个答案:

答案 0 :(得分:1)

理想情况下,您需要区分lostFocus和输入键盘。

这是您修改的示例:

merge(
  this._control.valueChanges.pipe(
    filter(() => this.autoComplete.focus === true),
    debounceTime(1000),
    distinctUntilChanged(),
  ),
  this._control.valueChanges.pipe(
    filter(() => this.autoComplete.focus === false),
    distinctUntilChanged(),
  ),
)
  .pipe(takeUntil(this.ngUnsubscribe))
  .subscribe((value) => {
    // Logic goes here
  });

通过这种方式,您已经合并了this._control.valueChanges的两个版本,一个负责键盘输入,另一个负责focuslost

答案 1 :(得分:1)

谢谢您的提问!

我认为您可以使用不同的数据“流”简化组件的结构。对我来说,将可观察对象视为流更容易。

基本思想是拆分事件流。在这种情况下,您将减少代码的耦合。如果这样做的话,将来您将可以轻松切换实施方式。

在这里您可以找到Stackblitz example来进行实施。

private lostFocusSubject = new Subject<void>();
  private keyUpSubject = new Subject<void>();
  private onDestroySubject = new Subject();
  keyUp$ = this.keyUpSubject.asObservable().pipe(takeUntil(this.onDestroySubject));
  lostFocus$ = this.lostFocusSubject.asObservable().pipe(takeUntil(this.onDestroySubject));

  request$ = this.keyUp$.pipe(
    debounceTime(500),
    switchMap(() => this.getEmulatedRequest()),
    takeUntil(this.onDestroySubject)
  )

  ngOnInit() {
    this.request$.subscribe(() => console.log('Request was processed'));
    this.keyUp$.subscribe(() => console.log('Key up was processed'));
    this.lostFocus$.subscribe(() => console.log('Lost focus was processed'));
  }

  ngOnDestroy() {
    this.onDestroySubject.next();
  }

  onLostFocus() {
    this.lostFocusSubject.next();
  }

  onKeyUp() {
    this.keyUpSubject.next();
  }

  private getEmulatedRequest(): Observable<number> {
    return timer(1000);
  }

再次感谢您提出问题。

我正在等待您的反馈。祝你好运,演示愉快。