天天看點

[轉] 前端中的MVC

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,但是,代碼變複雜了。的确,層次越多,需要做的工作也越多,這裡需要處理各層的通信。是以,具體怎麼設計,還是要分析場景,因地制宜。