RxSwift 观察数组的变化
Posted
技术标签:
【中文标题】RxSwift 观察数组的变化【英文标题】:RxSwift observing changes in array 【发布时间】:2018-07-04 16:05:02 【问题描述】:假设我们有 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
)
检测是否选择了集合中的所有项目
是否可以观察整个数组并根据元素更改对单个属性做出反应? 不知道我应该如何实现这一目标。
可能我对这个案子的处理是完全错误的。但是我不确定我应该如何以不同的方式在这里操作。
【问题讨论】:
【参考方案1】:entity
和 isSelected
变量需要是 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)的大部分复杂性来自于必须在 observables 中解包 observables。如果你能把它分解一下,或者从 InvoiceDataModel 中删除变量会更好。
【讨论】:
【参考方案2】:首先,请注意在 RxCocoa 中不推荐使用 Variable(改用 BehaviorRelay)。
一个简单的解决方案是将isSelected
可观察对象组合成一个单独的、发射量的可观察对象。我只是把这个 sn-p 放在一起,但它应该会为你指明正确的方向。
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,如果所有项目都被选中,则该 Observable 会发出。 (不要忘记.distinctUntilChanged()
,否则你会看到很多发射的元素。)
【讨论】:
以上是关于RxSwift 观察数组的变化的主要内容,如果未能解决你的问题,请参考以下文章
在 RxCocoa/RxSwift 中,如何观察 BehaviorRelay<[object]> 数组大小发生变化