如果我想在RxSwift中模拟例如Bool
的标准属性,我可以使用let isValid = Variable<Bool>(false)
,然后使用.value
获取内联的最后一个值,并.asObservable()
访问流。
但是我想模仿一个计算机,例如var isValid { return self.password.characters.count > 0 }
并且还能够以内联以及可观察流的形式获取最后一个值。
我希望能够做到这两点,所以我可以写代码......
if isValid.value { // isValid is Variable<Bool>
// ... do something ....
}
以及绑定到例如一个TextField
我知道我可以写成纯Observable
如下......
var isValid: Observable<Bool> {
return self.username.asObservable().map { username in // username is Variable<String>
return username.characters.count > 0
}
}
然后我必须重构前面的例子....
isValid.subscribe { isValid in
if isValid.element {
// ... do something ....
}
}.dispose(of: self.disposeBag)
那么我如何在RxSwift中表达一个计算属性,它可以作为内联值和流使用?
答案 0 :(得分:0)
我遇到了同样的问题,最终找到了一个看起来不干净但有效的解决方案。我会添加一个新的var valid: Bool = false
和一个订阅isValid
observable来更新它
isValid.subscribe(onNext:{[self self] value in self?.valid = valid})
使用此isValid
用于绑定和订阅,valid
用于命令式代码。
顺便说一下,您对isValid
的定义有点“不自然”,只需将其设为let isValid: Observable<Bool>
,然后将其分配到init
,如isValid = username.asObservable().map({$0.characters.count > 0})
更新
另一个解决方案是使用RxBlockling,您可以使用try! isValid.toBlocking().single()
获取当前值,但我认为这是一个更糟糕的解决方案,通常不推荐。
答案 1 :(得分:0)
试试这个:
let username = Variable("")
private let _isValid: Observable<Bool> = username.asObservable().map{ $0.characters.count > 0 }
let isValid = Variable(false)
然后,在init
,viewDidLoad
或任何地方:
_isValid.asObservable()
.bind(to: isValid)
.disposed(by: bag)
您可以使用以下方法进行测试:
isValid.asObservable()
.subscribe(onNext: {
print("value: \($0)")
})
.disposed(by: disposeBag)
username.value = "xfreire"
// OUTPUTS:
// value: false
// value: true
你仍然可以这样做:
if isValid.value {
// ...
}