我在结合可观察变量时有一个小(或大)问题。我正在实现某种标签输入。

this._allTags均为可用标签。

我有4个流:

  this._suggestions = new this.rx.Subject;
  this._searchText = new this.rx.Subject;
  this._selectedIndex = new this.rx.Subject;
  this._eventsStream = new this.rx.Subject;


搜索方式:

search(searchText) {
  this._searchText.onNext(searchText);
  this._selectedIndex.onNext(-1);
}


KeyDown方法:

keyDown(event) {
  this._eventsStream.onNext(event);
}


搜索逻辑:

  const partitionSearchText = this._searchText
    .partition((searchText) => !!searchText); //check if searchText is not empty

  //put filtered array to this._suggestions stream
  partitionSearchText[0]
    .subscribe((searchText) => this._suggestions.onNext(
        this._allTags.filter((item) => ~item.name.toLowerCase().indexOf(searchText.toLowerCase()))
      ));

   //put empty array to this._suggestions stream if there is no searchText
  partitionSearchText[1]
    .subscribe((searchText) => this._suggestions.onNext([]));


我想实施事件。如果有searchText和keyDown事件,那么我想增加this._selectedIndex,但是如果this._selectedIndexthis._suggestions长度相同,则不要增加它。

到目前为止,这是我实现的:

  const eventsWithSearchText = this._searchText
    .map((searchText) => !!searchText ? this._eventsStream : this.rx.Observable.empty())
    .switch()

  const keyDownEvents = eventsWithSearchText
    .filter((event) => event.keyCode === DOWN_KEY)

  keyDownEvents
    .subscribe((event) => event.preventDefault())

  const isNotLast = this._selectedIndex
    .combineLatest(this._suggestions, (index, sugg) => index !== sugg.length - 1);

  keyDownEvents
    .subscribe((item) => {
      this._selectedIndexValue++
      this._selectedIndex.onNext(this._selectedIndexValue);
    });


因此,当它与this._selectedIndex长度相同时,它会递增this._suggestions但不会停止。

你能帮我吗?

https://plnkr.co/edit/eh21d0d8U0VIsUyCjlkJ?p=preview

最佳答案

我做到了!这是代码:

  const eventsWithSearchText = this._searchText
    .map((searchText) => !!searchText ? this._eventsStream : this.rx.Observable.empty())
    .switch()

  const keyDownEvents = eventsWithSearchText
    .filter((event) => event.keyCode === DOWN_KEY)

  keyDownEvents
    .subscribe((event) => event.preventDefault())

  const keyUpEvents = eventsWithSearchText
    .filter((event) => event.keyCode === UP_KEY)

  keyUpEvents
    .subscribe((event) => event.preventDefault())

  const enterEvents = eventsWithSearchText
    .filter((event) => event.keyCode === ENTER_KEY)

  enterEvents
    .subscribe((event) => event.preventDefault())

  const isNotLast = this._selectedIndex
    .combineLatest(this._suggestions, (index, sugg) => index !== sugg.length - 1);

  const keyDownAndNotLast = keyDownEvents
    .map(() => +1)
    .withLatestFrom(isNotLast, (value, notLast) => notLast ? value : false)
    .filter((item) => item)

  const keyUpEventsAndNotFirst = keyUpEvents
    .map(() => -1)
    .withLatestFrom(this._selectedIndex, (value, index) => !!index ? value : false)
    .filter((item) => item)

  this.rx.Observable.merge(
    keyDownAndNotLast,
    keyUpEventsAndNotFirst,
    enterEvents
      .map(() => ({reset: true}))
    )
    .scan((acc, value) => value.reset ? -1 : acc + value, -1)
    .subscribe((item) => {
      this._selectedIndex.onNext(item);
    });


https://plnkr.co/edit/soaChC?p=preview

希望对别人有帮助。

09-30 16:23
查看更多