RxSwift(24)——MVVM双向绑定
在项目开发中,除了常用的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]
}
}
viewModel
让VC
变得轻量级,连接起了view
和model
,而RxSwift使这一切更加融洽。通过searchBar
与searchTextOb
绑定,searchData
和tableView
绑定,searchBar
有变化时,searchTextOb
响应然后进行请求,并通过map
返回序列化数据,直接显示到与之绑定的UI层。
通过UI响应,传到
VM
请求,在VM
处理完业务,再响应到UI,从而达到双向绑定效果。