MVVM的定义:
①. Model- model 在 MVVM 中没有真正的变化. 取决于你的偏好, 你的 model 可能会或可能不会封装一些额外的业务逻辑工作. 我更倾向于把它当做一个容纳表现数据-模型对象信息的结构体, 并在一个单独的管理类中维护的创建/管理模型的统一逻辑.
②. View- view 包含实际 UI 本身(不论是UIView代码, storyboard 和 xib), 任何视图特定的逻辑, 和对用户输入的反馈. 在 iOS 中这不仅需要UIView代码和那些文件, 还包括很多需由UIViewController处理的工作.
③. View-Model- 这个术语本身会带来困惑, 因为它混搭了两个我们已知的术语, 但却是完全不同的东东. 它不是传统数据-模型结构中模型的意思(又来了, 只是我喜欢这个例子). 它的职责之一就是作为一个表现视图显示自身所需数据的静态模型;但它也有收集, 解释和转换那些数据的责任. 这留给了 view (controller) 一个更加清晰明确的任务: 呈现由 view-model 提供的数据.
View-Model 的总结:
MVC 中的 MVVM:
为了图解表示, 我们颠倒了MVC中的V和C, 于是首字母缩写更能准确地反映出组件间的关系方位, 给我们带来MCV. 我也会对MVVM这么干, 将V(iew)移到VM的右边最终成为了MVMV. (我相信这些首字母缩写起初不排成这样更合理的顺序是有原因的. )
下面让我们来看个简单的映射:
a. 我试图遵循区块尺寸(非常)大致对应它们负责的工作量.
b. 你可以看到我们巨大的视图控制器和 view-model 之间有大块工作上的重合.
c. 你也可以看看视图控制器在 MVVM 中的足迹有多大一部分是跟视图重合的.
我们试图将重合的那块工作区域剥离到 view-model 中, 并让视图控制器的更加简洁。
实际上最终以MVMCV告终.ModelView-ModelControllerView作为结点。
现在视图控制器仅关注用 view-model 的数据配置和管理各种各样的视图, 并先于用户输入时让 view-model 获知并需要向上游修改数据. 视图控制器不需要了解关于网络服务调用, Core Data, 模型对象等. (事实上有时通过 view-model 头文件而不是复制一大堆属性来暴漏 model 是很务实的, 后面还会有)
view-model 会在视图控制器上以一个属性的方式存在. 视图控制器知道 view-model 和它的公有属性, 但是 view-model 对视图控制器一无所知.
帮助你理解我们如何把组件组装在一起还有组件对应职责的另一种方式, 就是着眼于我们新的应用构建模块层级图.
View-Model 和 View Controller 在一起,但独立
我们来看个简单的 view-model 头文件来,以便对你有个更好地概念. 为了情节简单, 我们构建按了一个伪造的推特客户端来查看任何推特用户的最新回复, 通过输入他们的姓名并点击 “Go”. 我们的样例界面将会是这样:
a. 有一个让用户输入他们姓名的UITextField, 和一个写着 “Go” 的UIButton
b. 有显示被查看的当前用户头像和姓名的UIImageView和UILabel各一个
c. 下面放着一个显示最新回复推文的UITableView
d. 允许无限滚动
view-model 不做的事:对视图控制器以任何形式直接起作用或直接通告其变化
View Controller要做的事:
视图控制器从 view-model 获取的数据将用来:
视图控制器不做的事:
注意:视图控制器总的责任是处理 view-model 中的变化.
视图控制器将对 view-model 起如下作用:
子 view-model的作用:
使用 view-model 上的tweets数组中的对象配置表格视图的 cell. 通常你会期待展现tweets的是数据-模型对象. 你可能已经对其感到奇怪, 因为我们试图通过 MVVM 模式不暴漏数据-模型对象. (前面提到过的)
view-model 不必在屏幕上显示所有东西.你可用子 view-model 来代表屏幕上更小, 更潜在被封装的部分. 如果一个视图上的一小块儿(比如表格的 cell)在 app 中可以被重用以及(或)表现多个数据-模型对象, 子 view-model 会格外有利
View-Model 产生 View-Model
假如我们想要在用户轻拍应用顶部的头像时添加一个资料视图控制器. 我们可以为一级 view-model 添加类似如下方法:
然后在我们的一级视图控制器中这么用它:
在这个例子中我将会展现当前用户的资料视图控制器, 但是我的资料视图控制器需要一个 view-model. 我这的主视图控制器不知道用于创建关联相关用户 view-model 的全部必要数据, 所以它请求它自己的 view-model 来干这种创建新 view-model 的苦差事.(这就助长和造成了逻辑混乱,代码烦乱的开始)
View-Model 列表
至于我们的推特 cell, 当数据驱动屏幕(在这个例子中或许是通过网络服务调用)聚到一起时, 我将会代表性地提前为对应的 cell 创建所有的 view-model. 所以在我们这个方案中,tweets将会是一个MYTweetCellViewModel对象数组. 在我的表格视图中的cellForRowAtIndexPath方法中, 我将会在正确的索引上简单地抓取 view-model, 并把它赋值给我的 cell 上的 view-model 属性.
MVVM(二)