首页 > 技术文章 > MVVM模式

shawnhu 2017-12-01 00:40 原文

  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:

  

 

推荐阅读