combineYatest用于Y个元素的前X个

时间:2017-01-13 21:08:53

标签: android rx-java rx-android rx-binding

我的观点有三个字段,它们共同形成一个等式。我想要实现的是,只要用户填写3个字段中的2个,我就会计算剩余的字段。

我有什么:

mObservableEditTextA = RxTextView.textChanges(mEditTextA);
mObservableEditTextB = RxTextView.textChanges(mEditTextB);
mObservableEditTextC = RxTextView.textChanges(mEditTextC);

我试着为每一对领域获得其他两个领域的最新组合而没有成功。

Observable.combineLatest(mObservableEditTextA, mObservableEditTextB, (a, b) -> /* My action here */);
Observable.combineLatest(mObservableEditTextA, mObservableEditTextC, (a, c) -> /* My action here */);
Observable.combineLatest(mObservableEditTextB, mObservableEditTextC, (b, c) -> /* My action here */);

我该如何实现这种行为?

1 个答案:

答案 0 :(得分:0)

可能有更好的方法,但你可以为每个事件附上一个发射时间戳,确定它们中的哪一个是最后一个并发出其余事件。通过它们来自的可观察(字段)识别这些事件,并由列表中缺少的元素决定。

mObservableEditTextA = RxTextView.textChanges(mEditTextA)
    .debounce(500, TimeUnit.MILLISECONDS) // So we don't flood the heap with lots of object construction, creating performance overhead due to garbage collection
    .map(text -> Pair.create(new Date(), text));
mObservableEditTextB = RxTextView.textChanges(mEditTextB)
    .debounce(500, TimeUnit.MILLISECONDS)
    .map(text -> Pair.create(new Date(), text));
mObservableEditTextC = RxTextView.textChanges(mEditTextC)
    .debounce(500, TimeUnit.MILLISECONDS)
    .map(text -> Pair.create(new Date(), text));

Observable.combineLatest(mObservableEditTextA, mObservableEditTextB, mObservableEditTextC, (fieldAPair, fieldBPair, fieldCPair) -> {
        firstField = ...;
        secondField = ...;
        // from timestamps determine which of the fields emitted last and return the other two with identifiers
        return Arrays.asList(Pair.create(firstFieldIdentifier, firstField), Pair.create(secondFieldIdentifier, secondField));
    })
    .subscribe(result -> {
        /* result is always a list of 2 items, more specifically 
           pairs of an identification in first position and new text 
           in the second. 

           Here you can look for the missing field in the list and 
           compute it from the other two */
    })

确定要计算哪一个的逻辑在此重复。我这样做只是因为不必将这些对象包装在一个新对象中,而嵌套的Pairs失去了可读性。

然而,您可以将列表中的位置视为该字段的标识符,尽管这很容易出错。

任何这些方法都会将确定逻辑从订户和combineLatest运营商仅移动到订户本身。你的电话。