做者:nuysoft/高雲/nuysoft@gmail.comcss
原文連接:http://www.cnblogs.com/nuysoft/archive/2012/03/18/2404274.htmlhtml
M 模型git
V 視圖github
C 控制器/分發器web
工具庫後端
MVC的模型Model、視圖View、控制器Control三個相互獨立又相互聯繫,C做爲其中的橋樑。MVC做爲由來已久的成熟開發模型,已經有經典的實現可控參考,在瀏覽器和JS這個特定應用場景中,咱們作以下探討:數組
M模型是自包含的,能夠嵌套包含,不會主動引用視圖和控制器;能夠是簡單的JSON對象/數組,也能夠用組合模式Composite實現嵌套包含;瀏覽器
V視圖是嵌套包含的,能夠用組合Composite實現;視圖須要引用模型(M-V),一個視圖引用一個多個視圖,視圖會收到模型的通知並自動更新,能夠用觀察者模式Observer實現;視圖須要響應用戶的交互,使用瀏覽器事件模型;服務器
C控制器做爲MVC框架關注的核心,採起集中配置的策略(V-C);能夠有多個控制器(C+C),用策略模式Strategy實現;hash事件驅動須要用到瀏覽器事件模型。閉包
能夠看到M模型和C控制器之間沒有關聯,通常我認爲是不須要的;可是在有的框架中實現了M模型和C控制器事件的關聯(好比公司在用的Magix),也是一種實踐,能夠參考。
上邊的論述解析MVC在JS中定位,可是理解JSMVC如何運行的關鍵在於對事件驅動的理解。
在瀏覽器中JSMVC有三種事件驅動方式:
1. hash驅動,經過popstate/hashchange事件驅動控制器(前邊有過介紹,後續結合Backbone的Router和History詳細講解它原理、實現、技巧)
2. DOM事件,用來驅動視圖(這個咱們已經很熟悉了)
3. 模型事件(業務模型事件和數據模型事件),用來驅動模型和模型結合(這個後續結合Backbone的Model講解)
今天就寫到這裏,下節介紹Backbone的架構、能作什麼、不能作什麼、以及還能擴展什麼。
http://documentcloud.github.com/backbone/
http://www.csser.com/tools/backbone/backbone.js.html
Backbone經過提供模型Models、集合Collection、視圖Veiew賦予了Web應用程序分層結構。經過如下方式實現分層結構:
模型Model綁定鍵值數據和自定義事件;
集合Colection是模型的有序或無序集合,帶有豐富的可枚舉API;
視圖View聲明事件監聽函數;
將模型、集合、視圖與服務端的RESTful JSON接口鏈接。
整個Backbone的源碼用一個自調用匿名函數包裹,能夠經過閉包特性引用變量(例如 previousBackbone、slice、splice等),同時避免污染全局命名空間。
總體結構以下,仍是很清晰的:
1: (function() {
2: Backbone.Events // 自定義事件
3: Backbone.Model // 模型構造函數和原型擴展
4: Backbone.Collection // 集合構造函數和原型擴展
5: Backbone.Router // 路由配置器構造函數和原型擴展
6: Backbone.History // 路由器構造函數和原型擴展
7: Backbone.View // 視圖構造函數和原型擴展
8: Backbone.sync // 異步請求工具方法
9: var extend = function (protoProps, classProps) { ... } // 自擴展函數
10: Backbone.Model.extend = Backbone.Collection.extend = Backbone.Router.extend = Backbone.View.extend = extend; // 自擴展方法
11: }).call(this);
Backbone必須依賴於 Underscore.js,DOM操做和AJAX請求依賴於第三方jQuery/Zepto/ender之一,也能夠經過 Backbone.setDomLibrary( lib ) 設置其餘的第三方庫。
能夠和任意對象合體(將方法賦值到其餘對象或原型上),合體後的對象能夠自定義事件,提供三個方法來綁定、移除、觸發自定義事件。
是 JavaScript 應用程序的核心,包含業務數據和對業務數據的讀寫和持久化,模型的主要方法包括讀寫和持久化。
集合是模型的有序集合,能夠在集合上綁定 "change" 事件,當集合中的任何模型發生變化時收到通知,集合也能夠監聽 "add" 和 「remove" 事件, 從服務器獲取數據,並能使用 Underscore.js 提供的全套方法。
爲了方便,在集合中的模型上觸發的任何事件都會在集合上直接觸發。這樣就能夠監聽集合中模型的指定屬性的變化。 例如:Documents.on("change:selected", ...)
集合的主要方法包括讀寫、維護和持久化。
Web應用程序一般須要爲重要頁面提供可連接、收藏、可分享的 URL。 直到最近, 錨文片斷(hash #page)能夠被用來提供這種固定連接;同時隨着 History API 的到來,錨文如今能夠用於處理標準 URLs (/page)。
Backbone.Router 爲客戶端頁面路由提供了許多方法,並能鏈接到指定的動做(actions)和事件(events)。對於不支持 History API 的舊瀏覽器,路由器提供了優雅的回調函數並能夠透明的進行 URL 片斷的轉換。
頁面加載期間,當應用程序已經建立了全部的路由表,須要調用 Backbone.history.start(),或 Backbone.history.start({pushState : true}) 確保路由初始 URL。
做爲全局路由器,用於處理 hashchange 或 pushState事件,匹配適合的路由表,並觸發回調函數。
若是使用帶有路由表的路由器,會自動建立一個History對象,此時不要再建立一個History對象,而是使用 Backbone.history。
Backbone 會自動判斷瀏覽器對 pushState 的支持,以作內部的選擇。 不支持 pushState 的瀏覽器將會繼續使用基於錨點的 URL 片斷。
關於官網疑惑:
若是兼容 pushState 的瀏覽器訪問了某個 URL 錨點,將會被透明的轉換爲真實的 URL。 注意使用真實的 URLs 須要 web 服務器支持直接渲染那些頁面,所以後端程序也須要作修改。
瀏覽器發起HTTP請求時並不會把錨文部分放在請求頭中,查看 http rfc2612 也沒有發現相關的說明,保留疑問。
http://www.w3.org/Protocols/rfc2616/rfc2616.html
視圖的使用至關方便,不須要判斷任何HTML、CSS,能夠任意JavaScript模板引擎集成。
通用的作法是,將界面組織成基於模型的詩句,當模型改變時視圖當即更新,而不須要重畫整個頁面。
再也不須要糾結於JSON對象、查找DOM元素、手動更新HTML,只需把視圖 render 方法綁定到模型的 change 事件,模型數據會當即顯示到UI上。
模型、集合、視圖、路由器都一個extend方法,用於擴展原型屬性和靜態屬性,建立自定義的視圖、集合、視圖、路由器類。