Rx

RxSwift(24)——MVVM双向绑定

2020-11-18  本文已影响0人  无悔zero

在项目开发中,除了常用的MVC开发模式,还有一种常用的开发模式就是MVVM

1.什么是MVVM
MVVM是Model-View-ViewModel的简写。它本质上就是MVC 的改进版。MVVM 就是将其中的View 的状态和行为抽象化,让我们将视图 UI 和业务逻辑分开。当然这些事 ViewModel 已经帮我们做了,它可以取出 Model 的数据同时帮忙处理 View 中由于需要展示内容而涉及的业务逻辑。MVVM(Model-View-ViewModel)框架的由来便是MVP(Model-View-Presenter)模式与WPF结合的应用方式时发展演变过来的一种新型架构框架。它立足于原有MVP框架并且把WPF的新特性糅合进去,以应对客户日益复杂的需求变化。

2.MVVM优点
MVVM模式和MVC模式一样,主要目的是分离视图(View)和模型(Model),有几大优点
1. 低耦合。视图(View)可以独立于Model变化和修改,一个ViewModel可以绑定到不同的"View"上,当View变化的时候Model可以不变,当Model变化的时候View也可以不变。
2. 可重用性。你可以把一些视图逻辑放在一个ViewModel里面,让很多view重用这段视图逻辑。
3. 独立开发。开发人员可以专注于业务逻辑和数据的开发(ViewModel),设计人员可以专注于页面设计,使用Expression Blend可以很容易设计界面并生成xaml代码。
4. 可测试。界面素来是比较难于测试的,测试可以针对ViewModel来写。

而RxSwift和MVVM可以很好地融合在一起,比如下面例子,场景是输入框搜索然后返回数据显示:

override func viewDidLoad() {
    super.viewDidLoad()
    //绑定信号
    self.searchBar.rx.text.orEmpty
        .bind(to: self.viewModel.searchTextOb)
        .disposed(by: disposeBag)
   // 数据层绑定UI
    self.viewModel.searchData.drive(self.tableView.rx.items){ (tableView, indexPath, model) -> TestTableViewCell in
        let cell = tableView.dequeueReusableCell(withIdentifier: "TestTableViewCell") as! TestTableViewCell
        cell.setUI(model)
        return cell
    }.disposed(by: disposeBag)
}
class ViewModel: NSObject {

    let searchTextOb = BehaviorSubject(value: "")

    lazy var searchData: Driver<[DataModel]> = {
        return self.searchTextOb.asObserver()
            .throttle(RxTimeInterval.milliseconds(300), scheduler: MainScheduler.instance)//相隔0.3秒发送一次,主线程
            .distinctUntilChanged()//搜索变动时才请求
            .flatMapFirst(resposeData)//下沉请求,回调结果
            .asDriver(onErrorJustReturn: [])//状态共享,主线程,错误返回
    }()
    // 数据请求
    func resposeData(_ iden: String) -> Observable<[DataModel]> {
        guard !iden.isEmpty, let url = URL(string: "") else {
            return Observable.just([])
        }
        return URLSession.shared.rx.json(url: url)
                .observeOn(ConcurrentDispatchQueueScheduler(qos: .background))//后台执行
                .map(parseData)//映射解析数据
    }
    // 数据序列化
    func parseData(_ json: Any) -> [DataModel] {
        guard let items = json as? [[String: Any]] else {return []}
        //第三方框架解析数据
        guard let result = [DataModel].deserialize(from: items) else { return [] }
        return result as! [DataModel]
    }

}

viewModelVC变得轻量级,连接起了viewmodel,而RxSwift使这一切更加融洽。通过searchBarsearchTextOb绑定,searchDatatableView绑定,searchBar有变化时,searchTextOb响应然后进行请求,并通过map返回序列化数据,直接显示到与之绑定的UI层。

通过UI响应,传到VM请求,在VM处理完业务,再响应到UI,从而达到双向绑定效果。

上一篇下一篇

猜你喜欢

热点阅读