VOOZH about

URL: https://read01.com/0exzRz.html

⇱ 從angularJS看MVVM - 壹讀


Saturday, Apr 11, 2026

從angularJS看MVVM

2015/02/08 來源:cnblogs
javascript厚積薄發走勢異常迅猛,導致現在各種MV*框架百家爭雄,MVVM從MVC演變而來,為javascript注入了全新的活力。我工作的業務不會涉及到angularJS[ng]這麼重量級的東西,只有自己閒暇之餘做的項目才能一嘗angularJS。我才疏學淺,而這個話題又很大,所以見到的實在有限,但凡有討論這些比較抽象的東西,必然有爭論。這一切都是探索過去未知的領域,無論誰對誰錯,任何的探索都是值得的。
MVC和MVVM

初次接觸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

👁 Image
...
Model View ViewModel - MVVM

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

  • Model:數據展現的對象模型

  • View:頁面UI

  • ViewModel:實現Model和View的雙向綁定
它們的工作模型應該是:Model<=>ViewModel<=>View

👁 Image
...

讓人比較困惑的是: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是庫,不要跟框架並提。"

我知道。只是感嘆一下。

參考
您可能感興趣
免責聲明:本文內容來源于cnblogs,文章觀點不代表壹讀立場,如若侵犯到您的權益,或涉不實謠言,敬請向我們提出檢舉
最新文章 / 服務條款 / 私隱保護 / DMCA / 聯絡我們

壹讀/READ01.COM