繁体   English   中英

RxSwift观察数组中的变化

[英]RxSwift observing changes in array

假设我们有InvoiceDataModel数组

private let invoices Variable<[InvoiceDataModel]> = Variable([])

class InvoiceDataModel { 
    let id: Variable<Int>
    var entity: Variable<InvoiceDto>
    var isSelected: Variable<Bool> 
}

点击复选框后,我正在更改isSelected的值。 我想要实现的是对isSelect的反应改为:

  • 计算所选项目的总金额(每个实体具有var amount: Double
  • 检测是否选择了集合中的所有项目

是否可以观察整个数组并对元素变化的单个属性做出反应? 不知道我该怎么做到这一点。

可能我对这个案子的态度是完全错误的。 但是我不确定我应该以不同的方式在这里操作。

entityisSelected变量需要是let而不是vars。

这是我提出的解决方案:

let selectedsAndAmounts = invoices
    .asObservable()
    .flatMapLatest {
        Observable.combineLatest($0.map {
            Observable.combineLatest($0.isSelected.asObservable(), Observable.just($0.amount)) { (isSelected: $0, amount: $1) }
        })
    }

let allSelected = selectedsAndAmounts
    .map { $0.map { $0.isSelected } }
    .map { $0.contains(false) == false }

let amountOfSelected = selectedsAndAmounts
    .map { $0.map { $0.isSelected ? $0.amount : 0 } }
    .map { $0.reduce(0, +) }

此解决方案中的大多数复杂性( selectedsAndAmounts observable)来自于必须在可观察对象中展开observable。 如果你可以稍微分解一下,或者从InvoiceDataModel中删除Variables会更好。

首先,请注意在RxCocoa中不推荐使用Variable(而是使用BehaviorRelay)。

一个简短的解决方案是将isSelected observable组合成一个单独的量发射可观察量。 我只是将这个片段扔到一起,但它应该指向正确的方向。

invoices
    // whenever the list changes, subscribe to the combined observable (and dispose of any previous subscriptions)
    .flatMapLatest { list in
        // merge all isSelected observables together
        return Observable.merge(list.map { $0.isSelected })
    }
    // when an element is emitted, that means some `isSelected` observable has changed its value
    // get the latest invoices array 
    .withLatestFrom(invoices)
    // convert it from a InvoiceDataModel array to a summed amount of all elements
    .map { $0.reduce(0) { $0 + $1.amount } }
    // log all events passing through
    .debug()
    .subscribe()
    .disposed(by: yourDisposeBag)

您可以使用类似的方法订阅在所有项都被选中时发出的Observable。 (不要忘记.distinctUntilChanged() ,否则你会看到很多发射的元素。)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM