码迷,mamicode.com
首页 > Web开发 > 详细

从angularJS看MVVM

时间:2015-07-31 09:04:33      阅读:128      评论:0      收藏:0      [点我收藏+]

标签:viewmodel   mvc   mvvm   angularjs   

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

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

从angularJS看MVVM

标签:viewmodel   mvc   mvvm   angularjs   

原文地址:http://blog.csdn.net/u011127925/article/details/47164751

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!