1

我有两个数据流:

  1. 布尔流,指示商品是否存在于购物篮中。
  2. 点击流,启动项目放入/删除到篮子/从篮子中删除。

首先,我想根据布尔流更改切换按钮的标题。这很简单。其次,我想将布尔流中的最新值和 Clicks 流中的事件结合起来,以启动放置或删除请求。

这是我到目前为止所尝试的:

// 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);
            }
        }
);

但是, combineLatest 并不能胜任我的工作。相反,它会导致递归,因为至少发生了一次点击事件,并且 inBasketStream 在操作完成时更新。Zip 也无济于事,因为篮子流中可能会从另一个地方更改,因此存在堆叠多个布尔值的场景,这将使 zip 过时(只是下一个,而可能已经有更多值了堆叠在)下一次点击事件的值。

所以,我需要一种方法来从布尔流中获取最后一个值,并在点击事件发生时使用它。当然,我可以为此使用一个布尔字段(订阅 inBasketStream 并更新它 onNext),但我认为它不符合功能性,并且必须有一个组合来处理这个问题而无需额外的字段/变量。

谢谢。

PS 两个 observables 都很热

4

1 回答 1

2

看看withLatestFrom。它只会在主要来源发出同时结合其他来源的最新值时传播。

ViewObservable.clicks(mPurchaseButton)
              .withLatestFrom(inBasketStream, 
                             (dontCare, inBasket) -> inBasket)
.subscribe(/*do your update*/);
于 2015-06-24T08:07:12.113 回答