概述
MVVM 是一种设计模式,VM 指的是ViewModel。相比MVC模式而言,VC更加单纯,只需关注页面展示,无需关心业务逻辑。主要业务集中在VM中,可以更方便的重用相似的业务逻辑。
以购物袋页面为例,在MVC模式下,是把页面生命周期相关方法、网络请求及回调方法、页面布局(如tableView代理方法)放在ViewController中,而在MVVM模式下,则把网络请求(拉取购物袋信息、商品添加删除、检查商品库存等请求)及回调放到了VM中。
网络请求
拉取购物袋信息
这里包括发出请求和接收数据两部分,重点看一下接收数据。一般流程是根据status.code判断是成功还是失败,如果成功,把data中的数据赋值给VM当中相关的属性,这些属性是公开的,可以被外部监听,同时设置了定时器时间;如果失败,则进行相应提示。这里用了信号的方式(如showAlertSubject和showNetErrorSubject)来传递status,也可以通过其它方式,但是不建议用公开属性来传递,因为status是一个临时状态,不适合长期保存。
- 商品的添加、修改、删除请求
商品的添加、修改、删除逻辑差不多,以商品添加为例,发出请求和接收数据两部分如下:
这里拉取成功之后会再去调用requestCartListInfoWithLoading 重新请求购物袋信息,失败则弹出相应提示或要求用户登录。
- 检查商品库存
检查商品库存的请求跟之前的请求也类似,主要是处理数据的方法handleCheckData:里面有一点不同,这里通过data.msg_code和登录状态来判断是提醒用户还是推到相应的页面。
推到其它页面的方法如下:
这里有一个pushedViewController,是购物袋页面的VC的一个弱引用对象,之所以这么做是因为在VM中里面做页面跳转比较方便,这里也可以通过一个代理方法通知页面去跳转。
二、数据展现
1. 提示信息
在VM中我们通过信号将loading状态,错误信息等传递出来,在VC中就要订阅这些信号,然后将数据从信号中取出来,并展现到UI上。信号是RAC里面的一个专业术语,可以简单将信号理解为一个事件,VM就是事件的发起者,VC就是事件的接收者。一个信号可以有一个或多个接收者,没有接收者的信号不会起作用。
- 业务数据
VM 中我们保存了业务数据,如dataSource,这些展现到UI上就是用户加入到购物袋的商品信息。
在setupRAC方法中,我们对dataSource的value做了一个过滤,并订阅了他的next事件,在next事件block中我们刷新了cartListTable。这样我们就能在dataSource有更新的时候立即刷新界面。
tableView的代理方法如下图所示(没有显示完全)
我们可以看到在tableView的代理方法里面,从cartVM.dataSource取值,然后作为数据源,这样VC只用负责数据的展现,不用关心数据到底是怎么得到的了。如果以后dataSource从本地缓存中读取,也不需要修改VC中的代码,这有利于以后数据的扩展和代码的维护,看的人也会更清楚的了解里面的业务逻辑。