js架构设计模式——从angularJS看MVVM
javascript厚积薄发走势异常迅猛,导致现在各种MV*框架百家争雄,MVVM从MVC演变而来,为javascript注入了全新的活力。我工作的业务不会涉及到 angularJS[ng] 这么重量级的东西,只有自己闲暇之余做的项目才能一尝angularJS。我才疏学浅,而这个话题又很大,所以见到的实在有限,但凡有讨论这些比较抽象的东西,必然有争论。这一切都是探索过去未知的领域,无论谁对谁错,任何的探索都是值得的。
本文内容如下:
- 前言
- Model View Controller - MVC
- Model View ViewModel - MVVM
- ViewModel
- AngularJS带来的活力
- 结语
前言
初次接触MVC是ASP.NET MVC,早前一直编写aspx的我接触到MVC之后爱的死去活来,深深的被它灵动简洁的思想所震撼,而当初的我js写的实在是渣,连jquery都用不好。也从未想到前端竟然也能够导入MVC这么抽象性的东西。
近年,前端的需求也越来越重,过去后端的处理大多数都转移到了前端,而javascript又十分争气,一雪过去被鄙夷的耻辱。过去的javascript只是辅助页面的展现搞一些炫丽的特效,而现在已经演变的成为数据展现、加工的主力——随着前端任务繁重——前端MV*乘势而起。
MV*的思想中心很一致:UI和逻辑分离,提取数据模型。
Model View Controller - MVC
MVC核心:Model(模型),View(UI),Controller(控制器)
- Model:数据展现的对象模型,例如一个列表页HTML对象的模型/数据库中表模型
- View:UI,Web页面中就是HTML
- Controller:处理/加工Model
它们的工作模型应该是:Controller=>Model=>View

Model View ViewModel - MVVM
MVVM核心:Model(模型),View(UI),ViewModel(视图模型)
- Model:数据展现的对象模型
- View:页面UI
- ViewModel:实现Model和View的双向绑定
它们的工作模型应该是:Model<=>ViewModel<=>View

让人比较困惑的是:MVVM中的Controller是什么?
ng和avalon都提供了名为Controller的方法,其实它们的意义和MVC一致:处理/加工Model。
ViewModel
初次使用angularJS(以下简称ng)让我觉得很迷茫,毕竟它颠覆了传统的DOM操作,过去的页面某个列表页的数据是拿到数据之后,要么封装成Model,要么写成一个方法然后展现到页面上,例如下面的代码:
(function () { var data = [{ name: 'linkFly', blog: 'http://www.cnblogs.com/silin6/' }],//拿到数据 html = ['<ul>'], $container = $('#container'); //拼接为HTML data.forEach(function (item) { html.push('<li>', item.name, ' - ', item.blog); }); html.push('</ul>'); //展现到页面 $container.html(html.join(''));})();
而使用ng的代码如下:
<ul data-ng-repeat="item in datas"><li>{{item.name}} - {{item.blog}} </li></ul>
var app = angular.module('demo', []).controller('demoController', function ($scope) {//ViewModel双向绑定$scope.datas = [{ name: 'linkFly', blog: 'http://www.cnblogs.com/silin6/' }];});
MVVM的核心思想:不用再关注数据如何呈现到页面,由框架更新Model和View。
ng也提供了自定义的ViewModel: directive(指令) ,代码如下:
<!DOCTYPE html><html xmlns="http://www.w3.org/1999/xhtml" data-ng-app="demo"><head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <title>ng demo</title> <script src="http://cdn.bootcss.com/angular.js/1.3.8/angular.min.js"></script></head><body data-ng-controller="demoController"> <hello data-ng-model="text"> <a href="javascript:;">i'm {{text}}</a> </hello> <script> var app = angular.module('demo', []).controller('demoController', function ($scope) { $scope.text = '***'; }).directive('hello', function () { //编写hello指令 return { restrict: 'E',//指定这个指令是Element类型的 scope: { text: '=ngModel' },//指定对象 link: function ($scope, $elem) { //注册事件 $elem.on('click', function () { //修改数据,双向绑定 $scope.text = $scope.text === '***' ? 'linkFly' : '***'; $scope.$apply(); }); } }; }); </script></body></html>
directive 可以让你的代码插件化/组件化,当你想要完成一个日历插件,可以使用directive来实现,directive是ng中的ViewModel,再看 ViewModel的本份:更新Model到View中。因为viewModel直面操作Model和View,所以所有的事件绑定、操作DOM的逻辑都 应该在ViewModel/ng的directive中。
再看我们之前MVVM的图:
ViewModel实现的双向绑定原理:从外部环境接收Model,呈现到View。从View接收行为(web中是浏览器的事件,例如鼠标点击之类的)再更新Model。
当理解了ViewModel的职责,我相信对于ng的directive理解将会很大。而数据的处理/加工,应该仍然留在Controller中。MVVM的本质也只是注入了一层ViewModel。
AngularJS带来的活力
其实主要源于ViewModel。
初次接触ng的directive深感迷茫,很大程度上对MVVM不理解。因为ng的directive的行为太过组件化,过了很久才明白其实我们自己编写javascript也是组件化的,其实这也映射着更好的的web思想: Web components 。
ng中的directive可以让那些编码中习惯瞎灌一通代码的小伙伴尝到组件化的甜头,前提是你们需要经历痛苦的思想转换。
未来迟早要到来,Web components是趋势。
ViewModel的思维颠覆了传统的javascript操 作DOM的行为,迎合MVC的思想又能够让javascript的逻辑更加的清晰。为了迎接ViewModel,ECMAScript下下一个版本 (ECMAScript 7,当前ECMAScript 5)准备了 Object.observe() ——监听/观察javascript对象:当被监听的对象发生变化,通知监听者,数据双向绑定的利器。
结语
其实如果能够理解ViewModel,那么MVVM框架中很多事情都将可以得到很明确的答案,多数时候我们总是在成型的编程思维上去敲代码,当引入了一个框架,就意味着你要接受它的思想,然而颠覆一个人的思想是一件很困难的事情,毕竟我们无法像盗梦空间里那样,悄悄注入一个想法,从此世界颠覆。
jQuery如此的卓越也体现了这点,在你刚开始使用它的时候就发现它并没有侵入你的思想,你仍然可以用自己的思维写出自己的代码,不得不说jQuery的理念得以让其在今天大行其道——专注DOM。
可能有人想说:"jQuery是库,不要跟框架并提。"
我知道。只是感叹一下。
参考
- Avalon-迷你易用的MVVM框架
- MVC,MVP和MVVM的图示
作者:linkFly
原文: http://www.cnblogs.com/silin6/p/4279965.html
出处: www.cnblogs.com/silin6/
声明:嘿!你都拷走上面那么一大段了,我觉得你应该也不介意顺便拷走这一小段,希望你能够在每一次的引用中都保留这一段声明,尊重作者的辛勤劳动成果,本文与博客园共享。
js架构设计模式——从angularJS看MVVM的更多相关文章
- angularJS看MVVM
从angularJS看MVVM javascript厚积薄发走势异常迅猛,导致现在各种MV*框架百家争雄,MVVM从MVC演变而来,为javascript注入了全新的活力.我工作的业务不会涉及到a ...
- js架构设计模式——前端MVVM框架设计及实现(一)
前端MVVM框架设计及实现(一) 最近抽出点时间想弄个dom模块化的模板引擎,不过现在这种都是MVVM自带的,索性就想自己造轮子写一个简单的MVVM框架了 借鉴的自然还是从正美的avalon开始了,我 ...
- js架构设计模式——你对MVC、MVP、MVVM 三种组合模式分别有什么样的理解?
你对MVC.MVP.MVVM 三种组合模式分别有什么样的理解? MVC(Model-View-Controller)MVP(Model-View-Presenter)MVVM(Model-View-V ...
- js架构设计模式——理解javascript中的MVVM开发模式
理解javascript中的MVVM开发模式 http://blog.csdn.net/slalx/article/details/7856769 MVVM的全称是Model View ViewMod ...
- js架构设计模式——前端MVVM框架设计及实现(二)
前端MVVM框架设计及实现(二) 在前端MVVM框架设计及实现(一)中有一个博友提出一个看法: “html中使用mvvm徒增开发成本” 我想这位朋友要表达的意思应该是HTML定义了大量的语法标记,HT ...
- js架构设计模式——MVC,MVP 和 MVVM 的图示及简单明了的区别说明
MVC,MVP 和 MVVM 的图示 复杂的软件必须有清晰合理的架构,否则无法开发和维护. MVC(Model-View-Controller)是最常见的软件架构之一,业界有着广泛应用.它本身很容易理 ...
- js架构设计模式——由项目浅谈JS中MVVM模式
1. 背景 最近项目原因使用了durandal.js和knockout.js,颇有受益.决定写一个比较浅显的总结. 之前一直在用SpringMVC框架写后台,前台是用JSP+JS+标签库,算是很 ...
- js架构设计模式——MVVM模式下,ViewModel和View,Model有什么区别
MVVM模式下,ViewModel和View,Model有什么区别 Model:很简单,就是业务逻辑相关的数据对象,通常从数据库映射而来,我们可以说是与数据库对应的model. View:也很简单,就 ...
- 从angularJS看MVVM
javascript厚积薄发走势异常迅猛,导致现在各种MV*框架百家争雄,MVVM从MVC演变而来,为javascript注入了全新的活力.我工作的业务不会涉及到angularJS[ng]这么重量级的 ...
随机推荐
- Android--paint应用举例
android 用paint,canvas 绘图 (1)主要用了paint ,canvas 两个类中的方法 (2)主要用了画线和画圆的方法. (3)drawline(起始点轴坐标,起始点y轴坐标,终点 ...
- PAT (Advanced Level) 1007. Maximum Subsequence Sum (25)
简单DP. 注意:If all the K numbers are negative, then its maximum sum is defined to be 0, and you are sup ...
- js优化与注意点
1.使用尽可能少的全局变量.尽量用var来声明变量,避免隐式使用全局变量. 隐式全局变量和明确定义的全局变量间有些小的差异,就是通过delete操作符让变量未定义的能力. 通过var创建的全局变量(任 ...
- OpenCV学习(20) grabcut分割算法
http://www.cnblogs.com/mikewolf2002/p/3330390.html OpenCV学习(20) grabcut分割算法 在OpenCV中,实现了grabcut分割算法, ...
- (二)Jquery Mobile介绍以及Jquery Mobile页面与对话框
Jquery Mobile介绍以及Jquery Mobile页面与对话框 一. Adobe Dreamweaver CS6 环境 最新版本的cs6会支持JM的使用,有自动提示功能,很强大.安装说明地 ...
- POJ 1584 A Round Peg in a Ground Hole
先判断是不是N多边形,求一下凸包,如果所有点都用上了,那么就是凸多边形 判断圆是否在多边形内, 先排除圆心在多边形外的情况 剩下的情况可以利用圆心到每条边的最短距离与半径的大小来判断 #include ...
- 《Android学习指南》目录
源:<Android学习指南>目录 Android学习指南的内容分类: 分类 描述 0.学习Android必备的Java基础知识 没有Java基础的朋友,请不要先看Android的课程,这 ...
- MongoDB 3.0 WiredTiger Compression and Performance
MongoDB3.0中的压缩选项 在MongoDB 3.0中,WiredTiger为集合提供三个压缩选项: 无压缩 Snappy(默认启用) – 很不错的压缩,有效利用资源 zlib(类似gzip) ...
- javascript(3)
使用javascript改进链接 摘自<javascript基础教程> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Trans ...
- Java中的Runtime类
Runtime类描述了虚拟机一些信息.该类采用了单例设计模式,可以通过静态方法 getRuntime()获取Runtime类实例.下面演示了获取虚拟机的内存信息: package Main; publ ...