将RxSwift可观测结果绑定到另一个可观测结果



我有一个可观察的对象,它管理一个名为Profile:的对象

class Profile {
let name. : String
let surname : String
let avatar: String?
}
Observable<Profile>

这个可观察的被绑定到视图模型,视图模型同时具有一个称为的可观察属性

var initialMarks:Observable<String>

这是名字和姓氏属性的首字母。如果化身属性为零,则会显示此首字母。

我有一个函数可以返回字符串中的首字母:

func initialLetters(first:String, second: String) -> String

我如何通过使用RxSwift任何运算符来实现这一点,以:

  1. 访问化身属性
  2. 检查是否为零
  3. 如果为零,则调用函数initialLetters
  4. 将函数initialLetters绑定到可观察的initialLetter

非常感谢。

这只是一个简单的映射。。。

这是它自己的视图模型。

func initialMarks(for profile: Observable<Profile>) -> Observable<String> {
return profile
.compactMap { profile in
if profile.avatar == nil {
return initialLetters(first: profile.name, second: profile.surname)
}
else {
return nil
}
}
}

如果你想把它嵌入到视图模型结构/类中,你可以这样做:

struct ViewModel {
let profile: Observable<Profile>
var initialMarks: Observable<String> {
return profile
.map { profile in
if profile.avatar == nil {
return initialLetters(first: profile.name, second: profile.surname)
}
else {
return ""
}
}
}
}

此外,上面的两个实现也有细微的不同,这取决于您想要什么。。。在第一个中,它只在化身为零时发出首字母,第二个在化身存在时发出空字符串,或者在化身为零时发出首字母。

对于这个特定的例子,您需要使用PublishSubject,这样您就可以绑定流initialMarksSubject并将其观察为Observable

设置

private var initialMarksSubject = PublishSubject<String>()
private let disposeBag = DisposeBag()
private func observeInitialMarks() {
profileObservable
.filter { $0.avatar == nil } // only take elements that have a nil avatar
.map { self.initialLetters(first: $0.name, second: $0.surname) } // transform profile to initialLetters of type String
.bind(to: initialMarksSubject) // bind the stream to your subject
.disposed(by: disposeBag)
}
var initialMarks: Observable<String> {
return initialMarksSubject.asObservable()
}

解释

调用observeInitialMarks()将:

  1. 订阅profileObservable
  2. 仅接受没有avatar的配置文件
  3. 将配置文件转换为initialLetters
  4. 将事件绑定到initialMarksSubject

订阅initialMarks将返回您需要为UI 显示的信息

UI组件的使用

viewModel.initialMarks
.observeOn(MainScheduler.instance)
.bind(to: profileLabel.rx.text)
.disposed(by: disposeBag)

最新更新