MVVM模式
MVVM是一种前端框架模式,框架模式主要是用来管理与组织代码,在复杂应用中,利用高内聚低耦合的思想,将代码分离组织到不同部分,每部分都有其关注点和职责,各部分间耦合度低,达到“关注点分离”目的,使整个应用更易管理、维护,每个部分可以单独更新、替换以及复用,从而达到整个应用的模块化。
一、概念
MVVM是公认的模式,要点是双向绑定技术和ViewModel,双向绑定更方便你同时维护页面上都依赖于某个字段的N个区域,而不用手动更新它们;而ViewModel用来粘合View和Model,让它们进一步分离和解耦,其主要由以下几部分组成:
View :显示数据和接受用户操作,与ViewModel中的数据,双向绑定,触发ViewModel中的事件,纯净的html代码,不夹杂或引用JS代码。
Model : 领域对象,提供业务数据以及对数据的逻辑处理,其在实际开发中,可能是来自多个接口的Dto对象,毕竟数据库结构对象不能向外暴露。
ViewModel :View和Model的连接器,让Model更加适合于View,ViewModel把Model的数据根据View所需的格式进一步转化,使View可以直接绑定,如把来自多个接口的DTO对象,进一步加工成ViewModel数据,其可以直接双向绑定到View,是真正将页面与数据逻辑分离的模式。UI层也有逻辑,这些逻辑都放在ViewModel中,所以MVVM是也是富客户端的模式。另外,View中元素的事件绑定到ViewModel中定义的方法。
总之,Model获取到原始数据,ViewModel进一步 加工,View直接显示,另外其中的网络操作可以分离到单独的类或服务中,ViewModel的方法响应View中事件,调用网络操作Model。
二、优点
低耦合:View可以独立于Model变化和修改,同一个ViewModel可以给多个View复用,可以做到View和Model变化互不影响。
可重用:可以把一些视图逻辑放在ViewModel中,让多个View复用。
独立开发:开发人员可以专注于业务逻辑和数据开发(ViewModel),界面设计人员可以专注于View的设计。
可测试性:清晰的View分层,使得表现层的业务逻辑测试更简单和容易。
三、与MVC比较
1、MVC的View与业务逻辑关联紧密,直接访问Model,View包含Model,MVVM的View与Model松耦合,数据直接从ViewModel中获取绑定。
2、MVC操作流程
用户操作 -> View(负责接收用户的输入操作)->Controller(业务逻辑处理)->Model(数据持久化)->View(将结果反馈给View)
3、MVVM操作流程
用户操作 -> View(负责接收用户的输入操作)->ViewModel(绑定数据以及绑定方法自动执行)->Model(数据更新或持久化)->ViewModel(从获取更新后进一步加工数据)->View(双向绑定ViewModel数据)
四、AngularJS与MVVM
View :专注于界面的显示和渲染,即包含一堆声明式Directive(指令)的视图模板。
Model :领域对象,与业务逻辑相关的数据的封装载体,不包含任何与界面显示相关的逻辑,Model不关心自己会被如何显示或操作,大部分Model都是来自于WebApi接口返回的数据或全局配置对象,AngularJS中的Service正是封装和处理这些与Model相关的业务逻辑的最佳方式,这些领域对象可以被Controller或其他Service复用。
ViewModel :让View和Model进一步分离和解耦,负责View和Model的交互和协作,它负责给View提供显示数据,以及供View操作Model的途径,AngularJS中$scope充当了ViewModel角色,$scope可以添加数据和交互行为函数,数据来源分两种,一种是展现信息的业务数据,直接从Model中获取,另一种是描述交互的派生数据,如某个保存按钮在编辑模式下才显示,可以定义一个$scoe.isEdit来控制保存按钮显示隐藏,开始是false,点编辑按钮后设置为true,View中保存按钮用ng-show='isEdit'绑定该数据来显示。
Controller :不是MVVM中的核心元素,但是在AngularJS中用来负责ViewModel即$scope的初始化,调用一个或多个Model相关的Serive来获取领域对象,还可以绑定上View中的交互事件,如ng-click事件,事件相应方法中调用Model相关Serive来操作Model。
可见View不能和Model直接交互,而是通过$scope这个ViewModel来实现与Model交互的。
五、KnockoutJS与MVVM
通过一个函数来创建表示ViewModel的类,需要绑定的数据和函数将作为该类的成员。
ViewModel:
View: