我如何通过RxJs这样做?

时间:2018-02-22 00:03:50

标签: rxjs

我有一个自动完成控件,在去抖后触发onAutoCompleteSearch(),我从服务器检索结果。但是,如果用户输入文本并按下输入(键代码13),则应该引发一个信号,该信号将取消自动完成的下一次调用。由于这是第三方控件,因此我无法控制在设定的去抖时间之后发生的onAutoCompleteSearch()调用。

我正在使用Subject进行信号传输:

private cancelAutoComplete$ = new Subject<boolean>();

如果用户点击输入密钥:

  onKeyUp(e) {
    if (e.keyCode === 13) {
      this.cancelAutoComplete$.next(true);   
      this.fireExecuteSearch();   // fire full search
    } else {
      this.fireSearchChange();    // trigger user input change
    }
  }

要执行自动填充时:

  onAutoCompleteSearch(e) {
    console.log('starting autocomplete!');

    this.cancelAutoComplete$
      .first()
      .defaultIfEmpty(false)
      .subscribe(c => {
        if (c) {
          console.log('autocomplete cancelled!');
        } else {
          console.log('execute the autocomplete!');
          this.executeAutoComplete.next(e.query);
        }
      });
  }

以上内容并不完全正常...我想做的是检查一个元素的cancelAutoComplete流,如果存在则将其从流中取出,如果取消标志为真,则中止自动完成。如果没有元素,则返回默认元素false,以便继续自动完成。

我怎样才能做到这一点?基本上,如果有来自onKeyUp的取消信号 - &gt; keycode 13 event我想中止呼叫,如果没有继续。

我知道我可以使用一个简单的布尔来跟踪它,但想知道如何通过RxJs主题来做。

1 个答案:

答案 0 :(得分:0)

首先,我将cancelAutoComplete$一个BehaviorSubject初始化为false。只要keyCode不是13,就发送false

private cancelAutoComplete$ = new BehaviorSubject<boolean>(false);

onKeyUp(e) {
  if (e.keyCode === 13) {
    this.cancelAutoComplete$.next(true); // prevent autocomplete
    this.fireExecuteSearch();   
  } else {
    this.cancelAutoComplete$.next(false); // allow autocomplete   
    this.fireSearchChange();
  }
}

然后我将takeUntil运算符用作executeAutoComplete流的一部分,如下所示:

onAutoCompleteSearch(e) {
  this.executeAutoComplete.next(e.query);
}

this.executeAutoComplete
  .switchMap(query => this.backend.fetchAutoCompleteResults(query).takeUntil(
     this.cancelAutoComplete$.filter(c => c === true)
  ))
  .subscribe(...);

我假设你的后端api被命名为this.backend.fetchAutoCompleteResults - 如果cancelAutoComplete$最初是true,那么takeUntil会中止它,或者当呼叫进入时true飞行。