JavaScript用戶端MVC架構 詳解不同架構用法

來源:互聯網
上載者:User

15 年前,許多人都使用 Perl 和 ColdFusion 之類的工具構建網站。我們經常編寫可以在頁面頂部查詢資料庫的指令碼,對資料應用必要的轉換,以及在同一個指令碼底部顯示資料。這類架構適合於向網站添加簡單 的 “Contact us” 表單。然而,隨著應用程式變得更加複雜,這種方法無法進行相應的擴充來處理更大的複雜問題。大部分 Web 應用程式現在已經對模型-視圖-控制器 (MVC) 架構進行了標準化,使用單獨的代碼實現商務邏輯、顯示邏輯和使用者互動(路由)邏輯。湧現出從 Spring MVC 到 Rails 的各種架構可以協助您快速實現基於 MVC 的 Web 應用程式。

幾年前,jQuery 是用於構建用戶端 JavaScript 應用程式的主流庫。然而,隨著應用程式中的 JavaScript 的複雜性日益增加,jQuery 成為一項處理複雜性的必要不充分技術。例如,用於待辦事項 (to-do) 列表的單頁面應用程式可以包含一個緊急待辦事項清單、一個完整的待辦事項清單、一個當日待辦事項清單,以及一個到期待辦事項清單。在刪除某個待辦事項時會 怎樣?如果任務很緊急但已到期,您可能需要手動編寫代碼來從視圖中的三個或四個不同位置中刪除該事項。如果刪除某個對象後需要您刪除或更改螢幕上顯示的其 他相關對象,這樣複雜性就會變得無法控制。

用戶端 MVC 架構旨在解決此類問題,並且大多數架構都表現出色。但是您如何從許多 JavaScript 用戶端 MVC 架構中選擇合適的架構。本文將從較高的層面簡要介紹其中一些最流行的架構。以及如何針對給定的用例選擇合適的架構。

Backbone.js

在使用率方面,Backbone 是目前為止最流行的用戶端 MVC 架構。它被廣泛應用於各個開發社區,Rails 開發人員對它的採用率一直較高,並出現了許多廣受歡迎的資源,比如 thoughtbot(一家備受尊敬的 Rails 諮詢公司)推出了 Backbone on Rails(參見 參考資料)。Backbone.js 的優勢在於它與具象狀態傳輸 Web 服務實現了良好的整合。如果您對後端資料使用 RESTful JavaScript Object Notation (JSON) 模型並遵循 Backbone 所期望的約定(與 Rails 中的約定匹配),那麼您不需要編寫任何代碼就可以將 Backbone 串連到伺服器,從而節省大量的時間。

在 Backbone 中,應用程式套件組合含集合(使用者或文章)、模型(單個使用者或文章)、視圖和路由器。Backbone.js 中的視圖是非預定的 (nonprescriptive),允許您使用自己喜歡的 JavaScript 模板或架構。路由器結合了 Rail 風格的路由器和一個傳統的 MVC 控制器,負責獲得給定的 URL 並通知架構要啟動並執行代碼。清單 1 中的 Backbone.js 路由器代碼給出了一個樣本。

清單 1. 範例 Backbone.js 路由器代碼

var Workspace = Backbone.Router.extend({

routes: {

“help”: “help”, // #help “search/:query”: “search”, // #search/kiwis “search/:query/p:page”: “search” // #search/kiwis/p7 },

help: function() {

....

},

search: function(query, page) {

.....

}

});

Backbone.js 附帶了一個 Underscore.js 副本。Underscore.js 是一組工具 + 生產力,可以通過更加功能化的方式簡化 JavaScript 的編寫,並支援一系列有用的基於集合的操作。它還包括 Backbone.history,後者可以協助您巧妙地處理頁面導航。

Backbone.js 主要優勢在於它與伺服器的自動整合。如果這樣做適合您的用例,那麼學習如何使用 Backbone.js 將是值得的。您可以通過一些架構在一兩個小時之內初步掌握可能需要花一到兩天學習的Backbone.js 基礎知識。這非常適合比較大的項目,這類項目至少持續幾周的時間。

Backbone.js 仍然算不上一種完好的解決方案。您可能需要編寫相當數量的代碼來處理潛在的記憶體泄露等問題。您還可能需要實驗幾種方法來查看呈現內容,之後才能找到真正滿足需求的方法。

Spine.js

Spine.js 通常與 Backbone.js 進行比較;它受到 Backbone.js 的影響,並在使用率方面與前者接近。Spine.js 包含類、模型、控制器和視圖,這比 Backbone.js 引入的集合更加傳統一些。

Spine.js 使用 CoffeeScript(參見 參考資料)編寫,這使它更加簡練且(依我看來)更易於讀取原始碼。要瞭解 Spine.js 如何工作,您需要熟悉 CoffeeScript。然而,您不必使用 CoffeeScript 構建 Spine.js 應用程式。但是,如果已使用 CoffeeScript 進行了構建,您可以訪問 CoffeeScript 特性(如類)。CoffeeScript 使用原型繼承而非經典繼承,因而無法支援在本地 JavaScript 中的類。CoffeeScript 使用了一些非常標準的模式,為希望使用它們的開發人員提供類。如果使用純 JavaScript 編寫 Spine.js 應用程式,您只需使用 ,後者使您不需要編寫 CoffeeScript 代碼就可以訪問類。

Spine.js 中的模型、控制器和視圖都使用類實現,因此可以同時編寫類和執行個體方法。模型負責處理商務邏輯,屬於模組類,您可以擴充並包括其他模組,從而混合重用屬性和 功能。模型可以自動序列化到 JSON 中,通過僅使用本機存放區實現持久化。或者可以使用 Asynchronous JavaScript + XML (Ajax) 將對象持久化到伺服器中。和 Backbone.js 一樣,Spine.js 現在提供了合理的預設設定,可以通過 Ajax 實現持久化,但是仍可以在必要時編寫自己的特定實現,並且非常簡單。清單 2 展示了來自一個 Spine.js 應用程式中的 CoffeeScript 代碼的樣本。

清單 2. Spine.js 應用程式中的 CoffeeScript

class Contact extends Spine.Model

@configure “Contact”, “first_name”, “last_name”

@filter: (query) ->

@select (c) ->

c.first_name.indexOf(query) is not -1

fullName: -> [@first_name, @last_name].join(‘ ’)

Spine.js 和 Backbone.js 兩者之間最主要區別是它們處理伺服器互動的方式。Backbone.js 在顯示響應之前將等待伺服器響應。如果試圖刪除、插入或更新某個元素,使用者介面 (UI) 直到操作成功完成才會重新整理。而 Spine.js 側重於即時更新 UI,而且在進行幕後處理時處理 Ajax 伺服器。這種更新是一種非常重要的實踐,也是在這兩種最佳化的擁有良好編檔的流行架構之間選擇時需要考慮的的主要因素。

如果您的目標是建立一種用戶端體驗,而對伺服器狀態的更新是次要的,那麼 Spine.js 可能是一種更好的選擇。如果仍然使用伺服器來檢查狀態變化的有效性則 Backbone.js 可能更適合。Spine.js 提供了響應性更好的 UI。但是,如果顯示成功刪除某個元素,只是讓伺服器發送一個響應,不允許您刪除該項,因為該項正在被其他人使用,那麼會發生什嗎?針對這個問題存在一些 應急方案,但是通常來講 Spine.js 更加適合使用者操作自有(而非共用)資料。Spine.js 的一個常見用例就是購物車,其中所有驗證都可以在用戶端處理。

Knockout

人們可能會爭論目前為止討論的這些工具是否是原本意義上的真正的 MVC 架構。Knockout 明確實現了模型-視圖-視圖-模型 (MVVM),而不是經典的 MVC。但是,不要因此而妨礙到您的決策制定。在選擇架構時,更重要的是查看所提供的功能而非首字母縮減詞或分類。

Knockout.js 在熟悉 MVVM 模型的 Microsoft .NET 開發人員之間特別受歡迎。對於主要問題是將模型狀態通過聲明的方式綁定到視圖用例,Knockout.js 是非常好的選擇。Knockout.js 對於前面提到的樣本待辦事項應用程式是非常理想的選擇,該應用程式的主待辦事項清單的子集都有自己的視圖,在刪除某個待辦事項後需要更新所有的列表。

在 Knockout.js 中,您將建立模型、視圖模型和視圖。與在 Spine.js 和 Backbone.js 中一樣,負責處理商務邏輯、驗證和與遠程伺服器互動的 Ajax(假設您不僅僅是建立一個本地應用程式)。視圖模型代碼負責保留和操作模型資料。例如一個視圖模型可能包含添加、編輯以及從列表中刪除內容項的方 法。視圖模型非常貼近於傳統的 MVC 架構中的控制器。視圖就是一些模板,包含將資訊呈現到螢幕的標記。在 Knockout.js 中,這些可以通過聲明的方式綁定到視圖模型(方便入門)。一些學員可以在一個小時內掌握並使用 Knockout,並可在三個小時內構建非凡 (non-trivial) 應用程式。

一般來講,Knockout.js 比較適合較小、較簡單的項目。人們往往將 Backbone.js 或 Spine.js 用於更大、更複雜的項目。也就是說,有經驗的 Knockout.js 開發人員可以建立非常複雜、同時又易於維護的應用程式。如果考慮使用 Knockout.js,您也應當考慮 Angular.js 和 Sammy.js(參見 參考資料),後兩者是兩種相對輕量級、易於啟動的架構。

Batman.js

Batman.js 是一種有趣的新架構,由 JSConf 在 2011 年推出,但是又經過了幾個月的時間才能夠通過下載擷取。Batman.js 已經開始受到一些喜歡並得到開發 MVC 應用程式的程式員的關注。表面上看,Batman 在易於入門、支援視圖聲明綁定方面與 Knockout.js 類似。Batman.js 提供了一些其他功能,包括可選的全棧 (full-stack) 架構,用於自動代碼產生器、構建工具甚至後端 Node.js 伺服器代碼,可以實現您的伺服器端 API。

和 Knockout.js 一樣,Batman.js 也使用視圖綁定。清單 3展示了一些範例視圖代碼。

清單 3. Batman.js 中的視圖程式碼範例

<ul id=“items">

<li data-foreach-todo=“Todo.all” data-mixin=“animation”>

<input type=“checkbox” data-bind=“todo.isDone” data-event-change=“todo.save” />

<label data-bind=“todo.body” data-addclass-done=“todo.isDone”

data-mixin=“editable”></label>

<a data-event-click=“todo.destroy">delete</a>

</li>

<li><span data-bind=“Todo.all.length”></span>

<span data-bind=“‘item’ | pluralize Todo.all.length”></span></li>

</ul>

清單 3中的代碼是有效 HTML5,包含一些額外的屬性,供 Batman 綁定資料和事件。在 Batman.js 中,您的應用程式套件組合含模型、視圖和控制器。模型支援驗證功能,能夠實現生命週期事件,包括一個內建的恒等映射 (identity map),並且可以被告知(主動記錄樣式)如何堅持使用 、Batman.RestStorageBatman.RailsStorage 或自定實現。視圖為一些 JavaScript 類,呈現用純 HTML 編寫的模板,還有一些用 data-* 屬性綁定模型資料並觸發事件處理器的構件。控制器為一些永久對象,處理來自視圖的事件,訪問模型資料,並呈現相應的視圖。

選擇一種 JavaScript 架構

如果您正在從事一個長期的大項目,那麼瞭解 Backbone.js 或 Spine.js 很有必要,因為它們獲得了廣泛的採用,可以解決您可能遇到的問題。然而,即使有了這些項目,您要明白您不是有必要使用一個成熟的伺服器端 MVC 架構,而是還需繼續編寫基礎架構代碼。

嘗試使用在視圖中用了聲明式綁定的架構將非常有必要。此類架構具有與 Backbone.js 之類的項目不同的優缺點。如果考慮使用聲明式視圖綁定,那麼花些時間研究一下更新的 Batman.js 架構提供的額外功能。雖然 Batman.js 不像其他架構那麼流行,但它正在快速發展,而且提供了比普通用戶端 MVC 架構更豐富的特性。

在不同架構中進行原型化,感受一下這些架構的用法,這樣做非常有必要。特別是對於用戶端 MVC 架構來說,原型化是從不同選項中進行選擇的最快速、最有效方法之一。一種方法是讓每個團隊成員花一到兩天的時間,使用不同的架構進行原型化,然後進行回 顧並討論結果。最壞的情況是,如果您還有一對架構需要從中進行選擇,那麼再額外花一天左右的時間構建二者的概念,直到選出最適合您的用例的架構。

考慮靈活性。仔細考慮您可以做哪些工作來降低對架構的依賴性,這對於許多架構來說是一個艱巨的任務。為將來 12 到 18 個月內遷移到另一個架構制定一個備份方案,以防您發現需求和所選的架構沒有按照預期進行。

結束語

JavaScript 用戶端 MVC 架構仍然不夠成熟。這個領域正在發生快速改變,缺少一致認可的最佳實務。對於較大的項目 Backbone.js 和 Spine.js 都是非常流行、具有良好支援的。如果傾向於聲明視圖綁定,那麼 Knockout.js 和 Batman.js 則都是不錯的選擇。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.