zoukankan      html  css  js  c++  java
  • angularJS看MVVM

    从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
    MVC

    Model View ViewModel - MVVM

    MVVM核心:Model(模型),View(UI),ViewModel(视图模型)

    • Model:数据展现的对象模型
    • View:页面UI
    • ViewModel:实现Model和View的双向绑定

    它们的工作模型应该是:Model<=>ViewModel<=>View
    MVVM

    让人比较困惑的是: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是库,不要跟框架并提。"
    我知道。只是感叹一下。

    参考

  • 相关阅读:
    CentOS查看CPU信息、位数、多核信息
    Linux常用命令大全
    chmod命令详细用法
    tar命令的详细解释
    yum和rpm命令详解
    LeetCode 241. Different Ways to Add Parentheses
    LeetCode 139. Word Break
    LeetCode 201. Bitwise AND of Numbers Range
    LeetCode 486. Predict the Winner
    LeetCode 17. Letter Combinations of a Phone Number
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/4280392.html
Copyright © 2011-2022 走看看