RxSwift之双向绑定

520 阅读1分钟

在MVVM的架构模式下,RxSwift可以很方便的实现双向绑定。(View -> VM -> View)
当前实现需求: 搜索框输入关键字 -> 网络请求搜索数据 -> tableview加载数据
思路:搜索框绑定一个BehaviorSubject(观察者), BehaviorSubject(序列)通过高阶函数转换搜索结果为新序列, 搜索结果绑定tableview

        // 双向绑定
        searchBar.rx.text.orEmpty
            .bind(to: viewModel.searchTextOB)
            .disposed(by: disposeBag)
        
        viewModel.searchData.drive(tableView.rx.items) { tb, indexPath, model -> LGTableViewCell in
            let cell = tb.dequeueReusableCell(withIdentifier: self.resuseID) as! LGTableViewCell
            cell.nameLabel.text = model.name
            cell.classLabel.text = model.url
            cell.selectionStyle = .none
            return cell
        }.disposed(by: disposeBag)

VM中的业务处理

class LGComprehensiveViewModel: NSObject {
    
    let searchTextOB = BehaviorSubject(value: "")//既是序列也是观察者
    
    //搜索的关键字作为序列 被搜索请求所订阅,有关键字变化时就会触发新的搜索
    lazy var searchData: Driver<[LGReposityModel]> = {
        return self.searchTextOB.asObservable()
            .throttle(RxTimeInterval.milliseconds(300), scheduler: MainScheduler.instance)
            .distinctUntilChanged()
            .flatMapLatest(LGComprehensiveViewModel.reponseData)
            .asDriver(onErrorJustReturn: [])
    }()
    
    static func reponseData(_ githubID: String) -> Observable<[LGReposityModel]> {
        guard !githubID.isEmpty, let url = URL(string: "https://api.github.com/users/\(githubID)/repos") else {
            return Observable.just([])
        }
        return URLSession.shared.rx.json(url: url)
            .retry()
            .observe(on: ConcurrentDispatchQueueScheduler(qos: .background))
            .map(LGComprehensiveViewModel.dataParse)//序列化
    }
    
    static func dataParse(_ json: Any) -> [LGReposityModel] {
        guard let items = json as? [[String: Any]] else { return [] }
        
        guard let result = [LGReposityModel].deserialize(from: items) else { return [] }
        
        return result as! [LGReposityModel]
    }
}
总结:searchTextOB(BehaviorSubject)既是序列又是观察者是实现双向绑定的关键,巧妙的利用高阶函数把观察者转为序列。订阅搜索框绑定searchTextOB,searchTextOB通过高阶函数获取搜索结果并转换成序列,searchData绑定tableview。 VM持有searchTextOB、searchData绑定tableview,实现了View(searchBar)-> VM ->View(tableView)的双向绑定。