淺談js中的MVC

來源:互聯網
上載者:User

標籤:數組   讀寫   提交   操作   length   刪除   應用   對象   text   

MVC是什嗎?

MVC是一種架構模式,它將應用抽象為3個部分:模型(資料)、視圖、控制器(分發器)

本文將用一個經典的例子todoList來展開

一個事件發生的過程(通訊單向流動):

1、使用者在視圖V上與應用程式互動

2、控制器C觸發相應的事件,要求模型M改變狀態(讀寫資料)

3、模型M將資料發送到視圖V,更新資料,展現給使用者

 

在js的傳統開發模式中,大多基於事件驅動的:

1、hash驅動

2、DOM事件,用來驅動視圖

3、模型事件(業務模型事件和資料模型事件),用來驅動模型和模型結合

所以js中的MVC的特點是:單向流動、事件驅動

一)模型

模型存放著應用的所有資料對象(業務資料、資料校正、增刪改查),比如,例子todoList中的store模型,存放每一條記錄與之有關的邏輯

資料時物件導向的,當控制器請求模型讀寫資料時,模型就將資料封裝成模型執行個體。任何定義在這個資料模型上的函數或邏輯都可以直接被調用。在本文的例子中採用localStorage也是類似道理的。儲存的Todos可以隨時被調用

模型不關心,不包含視圖和控制器的邏輯。它們應該是相互解耦的。這裡提一點,模型與視圖的耦合,顯然是違反MVC架構原則,但往往我們有時候卻因為業務關係而無法完全解耦

模型表現了領域特定的資料,當一個模型有所改變的時候,它會通知它的觀察者

二)視圖

視圖是呈現給使用者的,是使用者互動的第一入口。它定義配置、管理者每個頁面相應的模板與組件,它表現為一個模型的目前狀態,視圖通過觀察者模式監視模型,以獲得最新的資料,來呈現最新的頁面。

所以,頁面首次載入時,往往是從接受模型的資料開始

三)控制器

控制器(分發器),是模型和視圖之間的橋樑,集中式地配置和管理事件分發、模型分發、視圖分發,還用來許可權控制、異常處理等。我們的應用中往往是有多個控制器的

頁面載入完成後,控制器會監聽視圖的使用者互動(按鈕點擊或表單提交),一旦使用者發生互動時,控制器做出視圖的選擇,觸發控制器的事件處理機制,去派發新的事件,通知模型更新資料

Demo-todoList


最後這裡是一個用原生js寫的todoList,這個demo做的很簡陋,點擊輸入文字點擊確定就添加,刪除是直接點擊該行資訊

單獨分離開來舉例子不好講,所以在代碼中進行注釋。首先簡單理下下邊代碼的思路:

1、V層定義配置了一個顯示資料的字串模板,同時定義一個訂閱者的回呼函數render()用於頁面更新資料

2、C層監聽使用者的添加與刪除操作,添加是add()函數,他執行了回呼函數render,同時向M層寫入資料,通知M層改變,刪除操作同理

3、M層是本機存放區localStorage,類比一個儲存資料對象的後台模型

<!DOCTYPE html><html lang="en"><head>           <meta charset="UTF-8">            <title>todo</title></head><body><header>            <h3>待定事項</h3></header><main>           <ul id="todoList"></ul>           <input type="text" id="content">           <button id="confirm">確認</button></main><script>    (function(){                  const ADD_KEY=‘_todoList_‘                  const Utils={                   //類比Modal(實體模型)               store(key,data)                if(arguments.length>1){                  return localStorage.setItem(key,JSON.stringify(data));}else{        let storeData=localStorage.getItem(key);        return (storeData &&JSON.parse(storeData))||[];//這裡一定要設定初始值為[]}}}class Todo{          constructor(id,text=""){                  this.id=id;                 this.text=text}}           let App={                init(){                       //this.todos為一個儲存json對象的數組,是一個執行個體化的資料對象,可任意調用                  this.todos=Utils.store(ADD_KEY)                  this.findDom()                  this.bindEvent()                  this.render()//初始化渲染        },                     findDom(){                this.contentBox=document.querySelector("#content")this.confirm=document.querySelector("#confirm")this.todoList=document.querySelector("#todoList")this.todoListItem=document.getElementByTagName("li")},//類比Controller(商務邏輯層)bindEvent(){         this.confirm.addEventListener(‘click‘,()=>{         //要求模型M改變狀態,add()函數是寫入資料操作         this.add() },false)           this.todoList.addEventListener(‘click‘,(item)=>{//時間委託,最佳化效能           this.remove(item)},false)},//這裡勉強抽象成一個視圖吧view(){let fragment=document.createDocumentFragment()//減少迴流次數fragment=‘‘for(let i=0;i<this.todos.length;i++){ //一次性DOM節點產生//這裡使用拼接字串代替視圖的模板,//模板是用一種聲明的方式指定部分甚至所有的視圖對象fragment +=‘<li>&{this.todos[i].text}</li>}this.todoList.innerHTML=fragment},//render()函數作為一個訂閱者的回呼函數,資料的變化會反饋到模型store//換句話說:視圖通過觀察者模式,觀察模型store,當模型發生改變,觸發視圖更新render(){   this.view()Utils.store(ADD_KEY,this.todos)},getItemIndex(item){let itemIndexif (item.target.tagName.toLowerCase()===‘li‘){let arr=Array.prototype.slice.call(this.todoListItem)let index=arr.indexOf(item.target)return itemIndex=index}},add(e){ let id=Number(new Date())let text=this.contentBox.valuelet addTodo=new Todo(id,text)this.todos.unshift(addTodo)//模型發生改變this.render()//當模型發生改變,觸發視圖更新},remove(item){let index=this.getItemIndex(item)this.todos.splice(index,1)this.render()}}App.init()})()</script></body></html>

隨著介面和邏輯的複雜,用js或者jq去控制DOM是不現實的。上邊例子只是用原生js類比MVC的思想實現過程。真正地項目往往會依賴一些封裝好的優秀庫進行高效開發

 

MVC模式的優點

MVC編程把所有精力放在資料處理,儘可能減少對網頁元素的處理。對於有一定數量功能的網頁,MVC模式下強制規範代碼,簡化,減少重複代碼,使代碼易於擴充

MVC模式的弊端

1、清晰的構架以代碼的複雜性為代價,對小項目反而降低開發效率

2、控制層和視圖層耦合,導致沒有真正分離和重用

3、在同一商務邏輯下,如果存在多種視圖呈現,需要視圖定義配置多個模板引擎、資料解析,多次處理資料與頁面更新。代碼就充滿了各種選取器與事件回調,隨著業務的膨脹,變得難以維護

總結:其實,現在MVC在前端用得比較少了,因為它的局限性,催生了MVVM模式的流行與廣泛使用

淺談js中的MVC

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.