2017-10-28 60 views
0

我有(我认为)应该是一个常见的场景。在一个数组的可观察范围内组合Observable's

我有一个可能有子视图模型的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(如果我的hasChanges绑定后添加ChildViewModel,它将不会被考虑在内)。

我要的是ParentViewModelhasChangestrue如果它的任何的孩子hasChanges是也是如此。

另一个失败的尝试,如下所示:

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

这将返回有任何改变的最后一个孩子的最新值,但是如果两个孩子有变化和一个返回到初始值,它使它返回false,这不是我所需要的。

回答

0

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

另一种方法可能会被应用.merge()所有儿童观测,并在此基础之上做.combineLatest()