微信号:FrontDev

介绍:分享 Web 前端相关的技术文章、工具资源、精选课程、热点资讯

从angularJS看MVVM

2015-02-16 20:19 前端大全
点击上方蓝字↑↑↑,轻松关注哦~

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


/////////////////


1. 『前端大全』分享 Web 前端相关的技术文章、工具资源、精选课程、热点资讯,欢迎关注。微信号:FrontDev

(长按二维码↑↑↑自动可扫描)

http://web.jobbole.com/all-posts/

2. 点击“阅读原文”,查看更多前端文章。


 
前端大全 更多文章 5个典型的JavaScript面试题(上) Limu:JavaScript的那些书 Web开发:我希望得到的编程学习路线图 JavaScript基础工具清单 常用排序算法之JavaScript实现
猜您喜欢 个性化推荐是不是伪命题、Sheryl Sandberg、苹果、滴滴、LSTM与大写的污 | Five · 周末推荐​ 从工程师到团队Leader,我的8年心路历程 Content Provider详解 论长尾词 跨数据中心Docker镜像复制的开源实现 | Harbor Registry