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是库,不要跟框架并提。"

我知道。只是感叹一下。

参考##

作者:linkFly
声明:嘿!你都拷走上面那么一大段了,我觉得你应该也不介意顺便拷走这一小段,希望你能够在每一次的引用中都保留这一段声明,尊重作者的辛勤劳动成果,本文与博客园共享。

从angularJS看MVVM的更多相关文章

  1. angularJS看MVVM

    从angularJS看MVVM   javascript厚积薄发走势异常迅猛,导致现在各种MV*框架百家争雄,MVVM从MVC演变而来,为javascript注入了全新的活力.我工作的业务不会涉及到a ...

  2. js架构设计模式——从angularJS看MVVM

    javascript厚积薄发走势异常迅猛,导致现在各种MV*框架百家争雄,MVVM从MVC演变而来,为javascript注入了全新的活力.我工作的业务不会涉及到 angularJS[ng] 这么重量 ...

  3. 通过angularjs的directive以及service来实现的列表页加载排序分页

    前两篇:(列表页的动态条件搜索,我是如何做列表页的)分别介绍了我们是如何做后端业务系统数据展示类的列表页以及动态搜索的,那么还剩下最重要的一项:数据展示.数据展示一般包含三部分: 数据列头 数据行 分 ...

  4. 前端见微知著AngularJS备忘篇:温故而知新,可以为师矣

    话说以前JQuery刚出来的时候,真的是对个人的冲击蛮大的.记得当时我买的第一本书就是<锋利的JQuery>,藉由这本书开始,我从此以后的项目基本用上了JQuery,其给我带来的便利性是不 ...

  5. angularJs项目实战!01:模块划分和目录组织

    近日来我有幸主导了一个典型的web app开发.该项目从产品层次来说是个典型的CRUD应用,故而我毫不犹豫地采用了grunt + boilerplate + angularjs + bootstrap ...

  6. 通过angularjs的directive以及service来实现的列表页加载排序分页(转)

    前两篇:(列表页的动态条件搜索,我是如何做列表页的)分别介绍了我们是如何做后端业务系统数据展示类的列表页以及动态搜索的,那么还剩下最重要的一项:数据展示.数据展示一般包含三部分: 数据列头 数据行 分 ...

  7. 在AngularJS的controller外部直接获取$scope

    为了防止无良网站的爬虫抓取文章,特此标识,转载请注明文章出处.LaplaceDemon/SJQ. http://www.cnblogs.com/shijiaqi1066/p/5560843.html ...

  8. WPF MVVM 架构 Step By Step(2)(简单的三层架构示例及粘合代码GLUE code)

    我们第一步就是去了解三层架构和问题然后去看MVVM是怎么去解决这些问题的. 现在,感觉和事实是完全不同的两个东西.当你看到三层架构的框图的时候,你会觉得每层的职责被分配的很好.但是当你你真的去写代码的 ...

  9. AngularJS优缺点、使用场景

    AngularJS 优缺点 优点: AngularJS模板功能强大丰富,自带了极其丰富的angular指令. AngularJS是完全可扩展的,与其他库的兼容效果很好,每一个功能可以修改或更换,以满足 ...

随机推荐

  1. Android基于mAppWidget实现手绘地图(一)--简介

    http://lemberg.github.io/mappwidget/user_guide.html 最近在看一些导游类应用,发现一些景区的导览图使用的完全是自定义地图,也就是手绘地图.这种小范围使 ...

  2. Gephi可视化(二)——Gephi Toolkit叫板Prefuse

    继在园子里写的<Gephi可视化(一)——使用Gephi Toolkit创建Gephi应用>介绍了如何使用Gephi Toolkit工具集进行可视化编程后,本篇对Gephi Toolkit ...

  3. Android开发资源获取国内代理(转载)

    Android Dev Tools官网地址:www.androiddevtools.cn 收集整理Android开发所需的Android SDK.开发中用到的工具.Android开发教程.Androi ...

  4. Canny边缘检测算法原理及C语言实现详解

    Canny算子是John Canny在1986年提出的,那年老大爷才28岁,该文章发表在PAMI顶级期刊上的(1986. A computational approach to edge detect ...

  5. CNN笔记

    Deep Learning是全部深度学习算法的总称,CNN是深度学习算法在图像处理领域的一个应用. 转 http://blog.csdn.net/stdcoutzyx/article/details/ ...

  6. iframe的内容增高或缩减时设置其iframe的高度的处理方案

    WEB管理软件往往是如下结构的 用户点击子页tab切换中部的显示内容,在切换过程中需要保证前面的子页保持先前的状态.这种情况一般都使用iframe来来作为切换的子页显示内容. 但是这里有一个问题,if ...

  7. JS魔法堂:彻底理解0.1 + 0.2 === 0.30000000000000004的背后

    Brief 一天有个朋友问我“JS中计算0.7 * 180怎么会等于125.99999999998,坑也太多了吧!”那时我猜测是二进制表示数值时发生round-off error所导致,但并不清楚具体 ...

  8. 解决MVC EF Code First错误:Model compatibility cannot be checked because the EdmMetadata type was not included in the model.

    Model compatibility cannot be checked because the EdmMetadata type was not included in the model. En ...

  9. Mac下Vim配置语法高亮

    设置终端的字体颜色 如图,打开终端然后,选择偏好设置,再选择描述文件,再窗口左侧可以选择系统配置好的,或者你也可以自定义,最后别忘了把你的配置设置成默认就行 Vim语法高亮设置 只需要找到vimrc配 ...

  10. T-SQL删除重复数据

    数据重复分为两种情况:一种是每个字段都相同的完全重复,第二种是部分字段重复的结果集.比如Name字段重复,而其他字段不一定重复或者重复可以忽略. 第一种情况比较容易解决,使用select distin ...