Как остановить испускаемое значение, когда испускает другой наблюдаемый?

Имея два Observable, один из которых испускает событие mouseover (отклоняется на 500 мс), а другой - событие mouseout, я ищу возможность остановить первый Observable (mouseover) от испускания, когда происходит второй Observable (mouseout).

let mouseOutObservable = Observable.fromEvent($('.row'), 'mouseout')

Observable.fromEvent($('.row'), 'mouseover')
          .debounceTime(500)
          // .stopEmitingWhen(mouseOutObservable) --> how? possible?
          .subscribe(event => {
              // show tooltip
              mouseOutObservable.first()
                                .subscribe(() => {
                                   // destroy tooltip
                                });
          });

person Thomas Zuberbuehler    schedule 06.04.2016    source источник


Ответы (3)


takeUntil делает именно то, что вы хотите.

person Matt Burnell    schedule 06.04.2016

Предлагаемые Мэттом Бернеллом и Иваном Малагоном решения работают нормально, если нет соседних элементов. Но мои элементы строки действительно встречаются в таблице. Я написал свой вопрос как бы интерпретируемым. Применение их предложения кода приведет к полной отмене подписки / удалению подписки, но мне нужно решение, чтобы предотвратить поступление в подписку только текущего излучаемого значения.

Однако оба ответа действительно решают мой вопрос выше. ;-) Поэтому я принял краткий ответ Мэтта Бернелла.

Чтобы включить мое дополнительное требование, я придумал другое решение, которое объединяет оба наблюдаемых в один, с последующим использованием времени задержки и продолжением, только если последним событием является событие наведения мыши.

    Observable.fromEvent($('.row'), 'mouseover')
              .merge(mouseOutObservable)
              .debounceTime(500)
              .filter(event => event[ 'type' ] === 'mouseover')
              .subscribe(event => {
                  // ....
              });
person Thomas Zuberbuehler    schedule 06.04.2016

Вы можете получить объект подписки для события mouseover, а затем удалить эту подписку с помощью функции mouseout.

let mouseOutObservable = Rx.Observable.fromEvent($('.row'), 'mouseout')

let mouseOverObservable = Rx.Observable.fromEvent($('.row'), 'mouseover')
          .debounce(500);

let mouseOverObservableSubscription = mouseOverObservable.subscribe(() => { $('#output').append('<p>mouseover</p>'); });
mouseOutObservable.subscribe(() => {
  $('#output').append('<p>mouseout</p>');
  mouseOverObservableSubscription.dispose();
})
.row {
  min-height: 48px;
  background-color: orange;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/rxjs/4.0.6/rx.all.js"></script>

<div class="row">Mouse over me!</div>

<div id="output"></div>

person Ivan Malagon    schedule 06.04.2016
comment
Спасибо. Ваше решение работает, но имеет ограничение, если соседние элементы существуют. Смотрите мой собственный ответ. Однако вы привели меня к решению. ;-) - person Thomas Zuberbuehler; 06.04.2016