rx-swift - Observable.CombineLatest 绑定和订阅 RxSwift
问题描述
我正在开发一个使用有一些不一致的 API 的应用程序,我已经通过执行一些共享操作的这 2 个 observables 取得了结果,但第一个 ' servers ' 是一个绑定到 UITableView 的数组。
serversViewModel.servers
.asObservable()
.observeOn(MainScheduler.instance)
.bind(to: serversTableView.rx.items(cellIdentifier: ServersTableViewCell.identifier, cellType: ServersTableViewCell.self)) { [weak self] (row, element, cell) in
guard let strongSelf = self else { return }
cell.serverProxy.accept(element)
if let currentServer = strongSelf.serversViewModel.currentServer.value,
element == currentServer,
let index = strongSelf.serversViewModel.servers.value.firstIndex(where: { $0 == currentServer }){
strongSelf.serversTableView.selectRow(at: IndexPath(row: index, section: 0), animated: true, scrollPosition: .top)
}
}
.disposed(by: disposeBag)
serversViewModel.currentServer
.asObservable()
.observeOn(MainScheduler.instance)
.subscribe(onNext: { [weak self] (server) in
guard let strongSelf = self else { return }
if let server = server, let index = strongSelf.serversViewModel.servers.value.firstIndex(where: { $0 == server }){
strongSelf.serversTableView.selectRow(at: IndexPath(row: index, section: 0), animated: true, scrollPosition: .top)
}
else{
strongSelf.serversTableView.deselectAllItems(animated: false)
}
})
.disposed(by: disposeBag)
是否可以为两者创建一个组合的 observable 并将其用于绑定 UITableView?
谢谢
解决方案
你想用combineLatest
. 请注意,其中大部分实际上应该在您的视图模型中......
在下面的代码中,servers
常量是应该显示的服务器对象数组和当前服务器的索引路径的元组。每当任何一个发出新值时,servers
都会发出一个值。
以后你可能会发现以下文章对你有帮助:Recipes for Combining Observables in RxSwift
let servers = Observable.combineLatest(serversViewModel.servers, serversViewModel.currentServer) { (servers, server) -> ([Server], IndexPath?) in
let indexPath = server.flatMap { servers.firstIndex(of: $0) }
.map { IndexPath(row: $0, section: 0) }
return (servers, indexPath)
}
servers
.map { $0.0 }
.bind(to: serversTableView.rx.items(cellIdentifier: ServersTableViewCell.identifier, cellType: ServersTableViewCell.self)) { (row, element, cell) in
cell.serverProxy.accept(element)
}
.disposed(by: disposeBag)
servers
.map { $0.1 }
.bind(onNext: { [serversTableView] indexPath in
if let indexPath = indexPath {
serversTableView.selectRow(at: indexPath, animated: true, scrollPosition: .top)
}
else {
serversTableView.deselectAllItems(animated: false)
}
})
.disposed(by: disposeBag)
推荐阅读
- spring-boot - 获取相关 ID 为 158 的元数据时出错:{LEADER_NOT_AVAILABLE}
- ios - iOS - 没有重定向的 AppAuth
- javascript - 如何仅调试特定的产品元素?
- php - 为什么 Webklex\IMAP\Client::getFolders() 在 Exchange Server 上失败?
- ios - ipad:ipad 上更大的警报区域
- react-native - React Native 中的 react-jsx-parser
- python - 为什么当我说但在我用python说之前我的睡眠不睡觉
- c# - 肥皂消息连接
- typescript - 如何将属性函数的返回类型推断为属性的类型?
- javascript - Index.js:46 未捕获的类型错误:无法读取未定义的属性“生活方式”