首页 > 解决方案 > 如何为同一个控件上的不同事件实现不同的 debounceTime?

问题描述

我有一个从 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

}

所以第一个控制台日志是真的,带有 setTimeout 的那个是假的

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

我可能在这里遗漏了一些东西,但是

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

标签: javascriptangularrxjsprimeng

解决方案


感谢你的提问!

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

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

在这里,您可以找到Stackblitz 示例来玩转实现。

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);
  }

再次感谢您的提问。

我在等你的反馈。祝您在演示中玩得开心。


推荐阅读