从angularJS看MVVM

javascript厚积薄发走势异常迅猛,导致现在各种MV*框架百家争雄,MVVM从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对象:当被监听的对象发生变化,通知监听者,数据双向绑定的利器。

看到的一些对Mvvm模式的看法,觉得不太正确。

a.Code-Behind文件要保证绝对干净。

这个说法有些太绝对了,理想状态下,View层的Code-Behind文件中只有在构造函数中调用初始UI元素的一行代码及设置View层的DataContext为对于的ViewModel层。

其实,Code-Behind中还可以些一些UI的逻辑的,比如一些丰富的动画效果,或者直接设置某个元素的样式等。

不过,Code-Behind中确实是不可以写业务逻辑的。

b.ViewModel层不能是Model层的简单封装,ViewModel层也不能是View层的简单映射。ViewModel层和View层要绝对分离,ViewModel层要和View层一样去面向需求设计。

我觉得这样做有点太过了。

Mvvm的目的只是为了UI逻辑和业务逻辑的分离,你说业务逻辑和数据要写在哪一层呢?没错,Model层。

ViewModel层的主要责任是表现逻辑和状态,即ViewModel层是连接View层和Model层的。Model层的一些业务逻辑的状态是需要通过ViewModel层暴露给View层来反映给软件使用者的。

结语

其实如果能够理解ViewModel,那么MVVM框架中很多事情都将可以得到很明确的答案,多数时候我们总是在成型的编程思维上去敲代码,当引入了一个框架,就意味着你要接受它的思想,然而颠覆一个人的思想是一件很困难的事情,毕竟我们无法像盗梦空间里那样,悄悄注入一个想法,从此世界颠覆。

jQuery如此的卓越也体现了这点,在你刚开始使用它的时候就发现它并没有侵入你的思想,你仍然可以用自己的思维写出自己的代码,不得不说jQuery的理念得以让其在今天大行其道——专注DOM。

可能有人想说:”jQuery是库,不要跟框架并提。”

我知道。只是感叹一下。

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-10 10:46:33

从angularJS看MVVM的相关文章

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

近日来我有幸主导了一个典型的web app开发.该项目从产品层次来说是个典型的CRUD应用,故而我毫不犹豫地采用了grunt + boilerplate + angularjs + bootstrap + D3 + requirejs 的架构来实现它.angularjs早在去年6月份我就有所接触,将它应用在实验室项目的个别页面中,11月份在新浪的时候也将其推荐给了所在云事业部项目组.项目组老大程辉等人都是很有技术敏感性的人,大胆地采纳了我的建议,将之应用于原本使用dojo开发的项目前端模块上.然

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

话说以前JQuery刚出来的时候,真的是对个人的冲击蛮大的.记得当时我买的第一本书就是<锋利的JQuery>,藉由这本书开始,我从此以后的项目基本用上了JQuery,其给我带来的便利性是不可言喻的,至少在当时,我奉之若掌上明珠.但是做了几年开发以后,逐渐发现其不便利的地方,尤其是频繁操纵Dom的场合.写一个五级联动,不仅要操作ajax,而且要操纵dom,更需要兼顾ajax请求完成的顺序.开始用的五层嵌套来完成的,发现代码太难看,然后重构成了利用TimeOut来进行操纵的场合,结果发现在网速很差

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

我们第一步就是去了解三层架构和问题然后去看MVVM是怎么去解决这些问题的. 现在,感觉和事实是完全不同的两个东西.当你看到三层架构的框图的时候,你会觉得每层的职责被分配的很好.但是当你你真的去写代码的时候你会发现其实一些层被迫去做本不应该他们做的额外的事情(违反了SOLID原则的S). 这个额外的工作就是在UI-Model和Model-Data access之间的代码.让我们就把这些代码称为“GLUE”代码.有两种主要的逻辑会造成“GLUE”代码(也许我知道的并不够多,其他的可以自己发现): 1

WPF-MVVM模式学习笔记3——MVVM概念再次挖掘

通过上篇文章<WPF-MVVM模式学习笔记2--MVVM简单样例>中举了一个例子,我对MVVM大概有了一个比较浅显的意思.同时,看过前两篇文章的人,也知道我的这个系列的文章大多数来源于其他的博客,我其实只是起了一个汇总的作用,毕竟我也是在学习,肯定是要去网络上学习别人的笔记喽.本篇文章将以温故而知新的方式再次去理解MVVM,力求对MVVM的认识再深一个层次. 1.再看"M-V-VM" M:即Model,由现实世界抽象出来的模型. V:即View,视图,界面,该界面与用户输入

一、angularjs基础了解

说明:此处比较杂,目前没有统一的总结哦 angularjs 是mvvm框架 加载JS文件总是使用后缀为.min.js的文件,因为这些文件是经过压缩的,能提升应用的启动速度 模块说明: 1.config只能注入 provide 和 constant 2.factory.service 一般用于定义公共函数,使用factory需要返回一个对象,service与controller相似常用于保存临时数据 3.constant 只用于存放常量信息,这里避免使用全局变量,定义方法:angular.modu

WPF MVVM学习

转自https://my.oschina.net/unpluggedcoder/blog/536301 简介 简单的三层架构示例和 GLUE(胶水)代码问题 第一步:最简单的 MVVM 示例 - 把后台代码移到类中 第二步:添加绑定 - 消灭后台代码 第三步:添加执行动作和"INotifyPropertyChanged"接口 第四步:在 ViewModel 中解耦执行动作 第五步:利用 PRISM WPF MVVM 的视频演示 简介 从我们还是儿童到学习成长为成年人,生命一直都在演变.

angularjs脏检查

angularjs实现了双向绑定,与vue的defineProperty不同,它的原理在于它的脏检查机制,以下做了一些总结: angular.js介绍 AngularJs是mvvm框架,它的组件是vm组件,scope是vm组件的数据集合 AngularJs通过directive来声明vm的行为,它实现为一个watcher,监听scope的属性的变化,把最新的属性更新UI AngularJs的双向绑定:如:一个是将$scope属性值绑定到HTML结构中,当$scope属性值发生变化的时候界面也发生

2015前端各大框架比较(angular,vue,react,ant)

前端流行框架大比拼 angular vue react ant-design angularjs angular是个MVVM的框架.针对的是MVVM这整个事.angular的最主要的场景就是单页应用,或是有大量数据绑定的情况. 特性 双向数据绑定 ioc依赖注入 指令 上面这几点用起来确实很爽,随便指定个区域,配一个controller,然后里面的东西就都在scrope里了,确实很方便 如果各位想看,参见 https://github.com/i5ting/ionic_ninja/blob/ma

JS 框架之我感

对于一些js框架在我看来,都是将前端的表现动态化,即用动态js把html加载到页面上,如angularJS的MVVM开发模式(已接触),ReactJS的View层组件化(学习中),还有一些只听过没见过,没见过没听过的框架. 现在我感觉这种通过javascript动态写入到网页中的开发模式对于seo的支持是很不友好的,而从开发.维护角度看确实很大的创新. angularJS是通过项目开发学习到的,感觉还不错,由于对seo不友好,但是也开发了80%,访问速度也很快(应用的是单页模式,刚刚接触也只能参