从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是库,不要跟框架并提。"
我知道。只是感叹一下。

参考

angularJS看MVVM的更多相关文章

  1. 从angularJS看MVVM

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

  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. JAVA学习课第五 — IO流程(九)文件分割器合成器

    文件分割器 private static final int SIZE = 1024 *1024; public static void splitFile(File file) throws IOE ...

  2. 【Swift】学习笔记(四)——设置(Collection)

    Swift和其他语言也提供了两种类型的集合:数组和字典 数组:数组用来按顺序存储同样类型的数据,swift规定它是类型安全的,每个数组都有自己的类型也就是其它语言所说的泛型. 创建数组: 1.var ...

  3. MongoDB CRUD 基础知识

    建立一个良好的发展环境 环境win8 x64,下载并安装省略.经mongodb 的bin文件夹增加windows的path中,为以后使用方便. c盘新建存储目录:c:/data/db 执行服务:WIN ...

  4. OC本学习笔记Foundation框架NSString与NSMutableString

       一.NSString与NSMutableString         相信大家对NSString类都不陌生.它是OC中提供的字符串类.它的对象中的字符串都是不可变的,而它的子类NSMutable ...

  5. structs2注解+jsp+ajax实现post异步载入select

    流程: 1.点击载入btn发起异步请求post 2.后台处理请求返回数据 3.前端获取数据成功,对数据进行处理 前端: html:首先要导入jq包,不然怎么用ajax呢. <script typ ...

  6. tornado的GET POST方法样品展示

    举例说明get和post该方法的用途: 一.演示样例用的GET方法: import tornado.ioloop import tornado.web class MainHandler(tornad ...

  7. SQL Server 移动数据库

    原文:SQL Server 移动数据库 移动系统数据库在下列情况下可能很有用: 故障恢复.例如,数据库处于可疑模式下或因硬件故障而关闭. 计划的重定位. 为预定的磁盘维护操作而进行的重定位. 下列过程 ...

  8. CCFadeOut ,CCFadeIn 不能使用的原因

    CCFadeOut *action = CCFadeOut::create(0.5f);  image->runAction(action); 截取部分代码.以上是我写游戏时候遇到的问题代码, ...

  9. c++ primer plus(文章6版本)中国版 编程练习答案第八章

    编程练习答案第八章 8.1写输出字符串的函数,存在默认参数表示输出频率,莫感觉1.(原标题太扯了,的问题的细微变化的基础上,含义) //8.1编写一个输出字符串的函数.有一个默认參数表示输出次数,默觉 ...

  10. 60分钟Python快速学习(转)

    60分钟Python快速学习(给发哥一个交代) 阅读目录 第一步:开发环境搭建: 第一个Python功能:初识Python 02.Python中定义变量不需要数据类型 03.在Pythod中定义方法 ...