RxJS结合可观察量

时间:2016-03-04 16:29:02

标签: javascript angularjs ecmascript-6 rxjs observable

组合observable有一点(或很大)的问题。我正在实现某种标签输入。

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

1 个答案:

答案 0 :(得分:3)

我做到了!这是代码:

  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

希望它会对某人有所帮助。