在一个Observable of Array中组合Observable

时间:2017-10-28 23:10:28

标签: swift rx-swift

我(我认为)应该是一个常见的场景。

我有一个可能有子视图模型的ViewModel。两者(父母和子女)都有一个Observable<Bool>来反映他们是否有关于其原始状态的更改。

代码如下:

class ParentViewModel {
    var children = Variable<[ChildViewModel]>([])

    var hasChanges: Observable<Bool> {
        return Observable.combineLatest(children.value.map { $0.hasChanges })
            .map { (boolArray) in
                boolArray.reduce(false) { $0 || $1 }
        }
    }
}

class ChildViewModel: CustomStringConvertible {

    let title: Variable<String>
    private let originalValue: String

    var hasChanges: Observable<Bool> {
        return title.asObservable()
            .map { $0 != self.originalValue }
    }

    init(string: String) {
        title = Variable<String>(string)
        originalValue = string
    }

    var description: String {
        return "\(type(of: self)) - \(title.value)"
    }

}

此工作正常,但ParentViewModel的更改正在合并来自children.value的值,因此它不是真Observable(如果我之后添加ChildViewModel hasChanges的绑定,不会被考虑在内。

我想要的是ParentViewModel hasChanges true如果它的任何的孩子hasChanges也是如此。

另一次尝试失败,看起来如下:

children.asObservable()
    .flatMap { Observable.from($0) }
    .flatMap { $0.hasChanges }

这将返回最后一个有任何更改的子项的最新值,但是如果两个子项有更改并且一个返回原始值,则返回false,这不是我需要的。 / p>

1 个答案:

答案 0 :(得分:0)

首先, .reduce()仅在上游完成时才会发出。请尝试使用 .scan()

另一种方法可能是将 .merge()应用于所有子可观察对象并在其上执行 .combineLatest()