簡體   English   中英

RxJS結合可觀察物

[英]RxJS Combining observables

我在結合可觀察變量時有一個小(或大)問題。 我正在實現某種標簽輸入。

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長度this._selectedIndex同時不會停止。

你能幫我嗎?

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

希望對別人有幫助。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM