從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和邏輯分離,提取數據模型。javascript

Model View Controller - MVC

MVC核心:Model(模型),View(UI),Controller(控制器)css

  • Model:數據展示的對象模型,例如一個列表頁HTML對象的模型/數據庫中表模型
  • View:UI,Web頁面中就是HTML
  • Controller:處理/加工Model

它們的工做模型應該是:Controller=>Model=>View
MVChtml

Model View ViewModel - MVVM

MVVM核心:Model(模型),View(UI),ViewModel(視圖模型)前端

  • Model:數據展示的對象模型
  • View:頁面UI
  • ViewModel:實現Model和View的雙向綁定

它們的工做模型應該是:Model<=>ViewModel<=>View
MVVMjava

讓人比較困惑的是:MVVM中的Controller是什麼?
ng和avalon都提供了名爲Controller的方法,其實它們的意義和MVC一致:處理/加工Model。jquery

ViewModel

初次使用angularJS(如下簡稱ng)讓我以爲很迷茫,畢竟它顛覆了傳統的DOM操做,過去的頁面某個列表頁的數據是拿到數據以後,要麼封裝成Model,要麼寫成一個方法而後展示到頁面上,例以下面的代碼:git

(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的代碼以下:angularjs

<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。github

ng也提供了自定義的ViewModel:directive(指令),代碼以下:web

<!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是庫,不要跟框架並提。"
我知道。只是感嘆一下。

參考##

做者:linkFly
聲明:嘿!你都拷走上面那麼一大段了,我以爲你應該也不介意順便拷走這一小段,但願你可以在每一次的引用中都保留這一段聲明,尊重做者的辛勤勞動成果,本文與博客園共享。
相關文章
相關標籤/搜索