Observable.CombineLatest绑定并订阅RxSwift

时间:2019-06-17 13:45:43

标签: rx-swift

我正在开发一个使用具有一些不一致的API的应用程序,我已经通过执行两个共享操作的这两个可观察对象获得了结果,但是第一个“ 服务器”是一个数组绑定到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)

是否可以为两者创建一个可合并的可观察对象并将其用于绑定UITableView?

谢谢

3 个答案:

答案 0 :(得分:1)

您要使用combineLatest。请注意,其中大多数实际上应该在您的视图模型中...

在下面的代码中,servers常量是应显示的Server对象数组和当前服务器的索引路径的元组。无论何时发出新值,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)

答案 1 :(得分:1)

我会采取略有不同的方法。首先,我将考虑将可观察的组合返回到您已经构建的ViewModel中。无需在您的ViewController中使用此合成。

然后输出 组成信号以绑定到您的rx.items中。 您可以将对象包装成表格单元格视图模型,以控制是否以“选定状态”显示它们

然后还从您的viewModel输出currentServer,只需滚动到它即可。

答案 2 :(得分:0)

在RxSwift中有几种组合可观察对象的方法。对于您的特定情况,您将不得不选择最适合您的需求。一些运算符是:

combineLatest zip merge

阅读此documentation,以了解其每个功能的更多信息。