Положить/удалить из корзины с помощью Rx

У меня есть два потока данных:

  1. Логический поток, указывающий, существует ли элемент в корзине.
  2. Поток кликов, который инициирует добавление/удаление товара в/из корзины.

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

Вот что я пробовал до сих пор:

// handling the toggle button caption
inBasketStream.subscribe(inBasket -> {
    mPurchaseButton.setText(inBasket ? "Already in basket" : "Purchase");
});

// handling clicks and deciding whether to add or remove item
Observable.combineLatest(
        inBasketStream,
        ViewObservable.clicks(mPurchaseButton),
        (inBasket, onClickEvent) -> inBasket).subscribe(inBasket -> {
            if (inBasket) {
                mRemoveFromBasket.call(mItemId);
            } else {
                mAddInBasket.call(mItemId);
            }
        }
);

Однако, combLatest не выполняет мою работу. Вместо этого это приводит к рекурсии, поскольку произошло по крайней мере одно событие clicks, а inBasketStream обновляется по завершении операции. Zip также не очень поможет, так как поток в корзине может быть изменен из другого места, и, следовательно, существует сценарий для стекирования нескольких логических значений, что сделает zip устаревшим (только следующее, в то время как может быть уже больше значений с накоплением) значение при следующем событии клика.

Итак, мне нужен способ получить последнее значение из логического потока и использовать его всякий раз, когда происходит событие щелчка. Конечно, я мог бы использовать для этого логическое поле (подписаться на inBasketStream и обновить его при следующем), но я не чувствую, что оно соответствует функционалу, и должна быть композиция для решения этой проблемы без дополнительных полей/переменных.

Спасибо.

P.S. обе наблюдаемые горячие


person midnight    schedule 24.06.2015    source источник


Ответы (1)


Взгляните на withLatestFrom. . Он будет распространяться только тогда, когда первичный источник излучает, объединяя последние значения из других источников.

ViewObservable.clicks(mPurchaseButton)
              .withLatestFrom(inBasketStream, 
                             (dontCare, inBasket) -> inBasket)
.subscribe(/*do your update*/);
person paulpdaniels    schedule 24.06.2015
comment
Большой! RxJava также имеет экспериментальную реализацию здесь: github.com/ ReactiveX/RxJava/blob/1.x/ - person midnight; 24.06.2015