MVC是一種設計模式,它將應用划分為3個部分:數據(模型)、展現層(視圖)和用戶交互(控制器)。其中:
M - MODEL(模型)
V - VIEW(視圖)
C - CONTROLLER(控制器)
一個事件的發生是這樣的過程:
1. 用戶和應用產生交互。
2. 控制器的事件處理器被觸發。
3. 控制器從模型中請求數據,並將其交給視圖。
4. 視圖將數據呈現給用戶。
不用類庫或框架就可以實現這種MVC架構模式。關鍵是要將MVC的每部分按照職責進行划分,將代碼清晰地分割為若干部分,並保持良好的解耦。這樣可以對每個部分進行獨立開發、測試和維護。
M-模型
模型用來存放應用的所有數據對象。比如,可能有一個User模型,用以存放用戶列表、他們的屬性及所有與模型有關的邏輯。模型不必知道視圖和控制器的邏輯。任何事件處理代碼、視圖模板,以及那些和模型無關的邏輯都應當隔離在模型之外。將模型的代碼和視圖的代碼混在一起,是違反MVC架構原則的。模型是最應該從應用中解耦出來的部分。
當控制器從服務器抓取數據或創建新的記錄時,它就將數據包裝成模型實例。也就是說,我們的數據是面向對象的,任何定義在這個數據模型上的函數或邏輯都可以直接被調用。
V-視圖
視圖層是呈現給用戶的,用戶與之產生交互。在JavaScript應用中,視圖大都是由HTML、CSS、JavaScript模板組成的。除了模板中簡單的條件語句之外,視圖不應當包含任何其他邏輯。將邏輯混入視圖之中是編程的大忌,這並不是說MVC不允許包含視覺呈現相關的邏輯,只要這部分邏輯沒有定義在視圖之內即可。我們將視覺呈現邏輯歸類為“視圖助手”(helper):和視圖相關的獨立的小工具函數。
C-控制器
控制器是模型和視圖之間的紐帶。控制器從視圖獲取事件和輸入,對它們(很可能包含模型)進行處理,並相應地更新視圖。當頁面加載時,控制器會給視圖添加事件監聽,比如監聽表單提交或按鈕點擊。然后,當用戶和你的應用產生交互時,控制器中的事件觸發器就開始工作了。
在網頁交互中,可以這樣理解:
1.用戶點擊了表格中的數據
2.觸發了點擊事件,數據變成可編輯的狀態(這個時候會出現一個文本框,但是里面還沒有數據)
3.第2步的點擊事件從存放數據的模型中把數據放到文本框中,形成一種數據由不可編輯到可編輯的一種效果
舉個例子:
<select id="drinkSelect"> <option value="coffee">coffee</option> <option value="milk">milk</option> <option value="juice">juice</option> </select> <p id="theColorOfDrink"></p> <script type="text/javascript"> document.getElementById("drinkSelect").onchange = function() { var color; var colorOfDrink = { "coffee":"brown", "milk":"white", "juice":"orange" }; color = colorOfDrink[this.value]; document.getElementById("theColorOfDrink").innerHTML = color; } </script>
上面程序會把選中的飲料的顏色顯示出來,如果用MVC,就是這個樣子:
<select id="drinkSelect"> <option value="coffee">coffee</option> <option value="milk">milk</option> <option value="juice">juice</option> </select> <p id="theColorOfDrink"></p> <script type="text/javascript"> //showDrinkColor is Controller var showDrinkColor = { start:function(){ this.view.start(); }, set:function(drinkName){ this.model.setDrink(drinkName); } }; //Model showDrinkColor.model = { colorOfDrink:{ "coffee":"brown", "milk":"white", "juice":"orange" }, selectedDrink:null, setDrink:function(drinkName){ this.selectedDrink = this.colorOfDrink[this.selectedDrink]?drinkName:null; this.onchange(); }, onchange:function(){ showDrinkColor.view.update(); }, getDrinkColor:function(){ return this.selectedDrink?this.colorOfDrink[this.selectedDrink]:"white"; } }; //View showDrinkColor.view = { start:function(){ document.getElementById("drinkSelect").onchange = this.onchange; }, onchange:function(){ showDrinkColor.set(document.getElementById("drinkSelect").value); }, update:function(){ document.getElementById("theColorOfDrink").innerHTML = showDrinkColor.model.getDrinkColor(); } }; showDrinkColor.start(); </script>
進行分層之后,各個層次的功能清晰:V層控制界面顯示,將界面與數據連接;M層存放數據,處理邏輯,C層用於連接M和V,但是,代碼變復雜了。的確,層次越多,需要做的工作也越多,這里需要處理各層的通信。所以,具體怎么設計,還是要分析場景,因地制宜。