與 Web 開發同業不同,JavaScript 從來沒有真正以框架的方式提供結構。值得慶幸的是,近年來,這種情況開始改變。
今天,我想向您介紹 Backbone.JS,這是一個可愛的小庫,它使創建複雜、互動式和資料驅動的應用程式的過程變得更加容易。它提供了一種乾淨的方法來將數據與簡報分開。
Backbone 由構建 CoffeeScript 的 JS 忍者 Jeremy Ashkenas 創建,是一個超輕量級庫,可讓您創建易於維護的前端。它與後端無關,並且可以與您已經使用的任何現代 JavaScript 庫配合良好。
Backbone 是一個內聚物件的集合,重量4kb以下,它為您的程式碼提供結構,基本上可以幫助您在瀏覽器中建立適當的 MVC 應用程式。官方網站是這樣描述其目的的:
Backbone 透過提供具有鍵值綁定和自訂事件的模型、具有豐富的可枚舉函數API 的集合、具有聲明性事件處理的視圖,為JavaScript 密集型應用程式提供結構,並將其全部連接到您現有的應用程式RESTful JSON 介面。
讓我們面對現實:上面的內容有點難解析和理解。因此,讓我們在 Jeremy 的幫助下繼續解構這些行話。
當模型的內容或狀態發生變更時,已訂閱該模型的其他物件會收到通知,以便它們可以進行相應的處理。在這裡,視圖監聽模型中的變化,並相應地更新自己,而不是模型必須手動處理視圖。
Backbone 附帶了許多非常有用的函數來處理和使用您的資料。與其他實作不同,JavaScript 中的陣列是相當中性的,當您必須處理資料時,這確實是一個阻礙問題。
你寫義大利麵條式綁定呼叫的日子已經結束了。您可以透過程式設計方式聲明哪個回呼需要與特定元素關聯。
儘管當您想要與伺服器通信時預設方法是使用標準 AJAX 調用,但您可以輕鬆地將其切換為您需要的任何內容。許多適配器如雨後春筍般湧現,涵蓋了大多數最受歡迎的適配器,包括 Websockets 和本地儲存。
將其分解為更簡單的術語:
Backbone 提供了一種乾淨的方法來將資料與簡報分開。處理資料的模型只關心與伺服器同步,而視圖的主要職責是監聽訂閱模型的變更並呈現 HTML。
我猜您現在可能有點困惑,所以讓我們澄清一些事情:
沒有。它們的範圍非常互補,功能上幾乎沒有重疊。 Backbone 處理所有較高層級的抽象,而 jQuery(或類似的函式庫)則處理 DOM、規範化事件等。
它們的範圍和用例非常不同,因為你知道其中一個並不意味著你不應該學習另一個。作為 JavaScript 開發人員,您應該知道如何有效地使用兩者。
因為通常情況下,前端程式碼會變成一堆熱氣騰騰、髒兮兮的嵌套回呼、DOM 操作、用於演示的 HTML 以及其他不可言喻的行為。
Backbone 提供了一種非常乾淨和優雅的方式來管理這種混亂。
Backbone 非常適合創建前端重型、數據驅動的應用程式。想想 GMail 介面、新 Twitter 或過去幾年的任何其他啟示。它使創建複雜的應用程式變得更加容易。
雖然您可以將其硬塞到更主流的網頁頁面,但這實際上是一個專為網頁應用程式量身定制的程式庫。
是和否。
是的,因為與上面提到的框架一樣,這主要用於為 Web 應用程式建立複雜的前端。
它的不同之處在於 Backbone 非常精簡,並且沒有附帶其他小部件。
Backbone 的重量非常輕,不到 4kb。
還有一個事實是,Cappuccino 強制您使用 Objective-J 編寫程式碼,而 Sproutcore 的視圖必須在 JS 中以程式設計方式宣告。雖然這些方法都沒有錯,但使用 Backbone,普通的 JavaScript 可以透過常用的 HTML 和 CSS 來完成工作,從而實現更溫和的學習曲線。
絕對是的。不僅是典型的 DOM 存取、AJAX 包裝類型,還有其餘的模板和腳本載入類型。它的耦合非常非常鬆散,這意味著您可以將幾乎所有工具與 Backbone 結合使用。
不,抱歉。但這裡有一些東西可以讓你振作起來。
好的,現在拋開這個問題,讓我們開始吧!
Backbone 中的 MVC 最初代表模型、視圖和集合,因為框架中沒有控制器。此後情況發生了變化。
Backbone 的核心由四個主要類別組成:
由於我們時間有點緊張,所以我們今天只看核心課程。我們將使用一個超級簡單的應用程式進行後續操作,以演示此處教授的概念,因為將所有內容都放在一篇文章中並期望讀者解析所有內容會太多。
在接下來的幾週內請保持警覺!
模型在不同的 MVC 實作中可能有不同的意義。在 Backbone 中,模型代表一個單一實體-資料庫中的記錄(如果您願意的話)。但這裡沒有硬性規定。來自 Backbone 網站:
模型是任何 JavaScript 應用程式的核心,包含互動式資料以及圍繞它的大部分邏輯:轉換、驗證、計算屬性和存取控制。
該模型只是為您提供了一種在資料集上讀取和寫入任意屬性或屬性的方法。考慮到這一點,下面的單行程式碼是完全可用的:
var Game = Backbone.Model.extend({});
讓我們在此基礎上進一步發展。
var Game = Backbone.Model.extend({ initialize: function(){ alert("Oh hey! "); }, defaults: { name: 'Default title', releaseDate: 2011, } });
initialize
將在實例化物件時被觸發。在這裡,我只是提醒大家注意一些愚蠢的行為——在您的應用程式中,您可能應該引導資料或執行其他內務處理。我還定義了一堆預設值,以防沒有資料被傳遞。
我們來看看如何讀寫屬性。但首先,讓我們建立一個新實例。
// Create a new game var portal = new Game({ name: "Portal 2", releaseDate: 2011}); // release will hold the releaseDate value -- 2011 here var release = portal.get('releaseDate'); // Changes the name attribute portal.set({ name: "Portal 2 by Valve"});
如果您注意到 get/set 變體器,請吃一塊 cookie!無法透過典型的 object.attribute 格式讀取模型的屬性。您必須執行 getter/setter,因為錯誤更改資料的可能性較低。
此時,所有變更僅保留在記憶體中。讓我們透過與伺服器對話來使這些變更永久生效。
portal.save();
就是這樣。你期待更多嗎?上面的一行程式碼現在將向您的伺服器發送一個請求。請記住,請求的類型會智慧地改變。由於這是一個新對象,因此將使用 POST。否則,使用 PUT。
Backbone 模型預設提供更多功能,但這絕對可以幫助您入門。點擊文件以獲取更多資訊。
Backbone 中的集合本質上只是模型的集合。與先前的資料庫類比一樣,集合是查詢的結果,其中結果由許多記錄[模型]組成。您可以像這樣定義一個集合:
var GamesCollection = Backbone.Collection.extend({ model : Game, } });
首先要注意的是,我們正在定義這是哪個模型的集合。擴展我們之前的範例,我將這個集合作為遊戲集合。
現在您可以繼續隨心所欲地使用您的資料。例如,讓我們擴展該集合以添加僅返回特定遊戲的方法。
var GamesCollection = Backbone.Collection.extend({ model : Game, old : function() { return this.filter(function(game) { return game.get('releaseDate') < 2009; }); } } });
這很容易,不是嗎?我們僅檢查遊戲是否在 2009 年之前發布,如果是,則退回該遊戲。
您也可以直接操作集合的內容,如下所示:
var games = new GamesCollection games.get(0);
上面的程式碼片段實例化了一個新的集合,然後檢索 ID 為 0 的模型。您可以透過引用 at 方法的索引來尋找特定位置的元素,如下所示: 遊戲.at(0);
#最後,您可以像這樣動態填充您的集合:
var GamesCollection = Backbone.Collection.extend({ model : Game, url: '/games' } }); var games = new GamesCollection games.fetch();
我們只是讓 Backbone 透過 url 屬性從何處取得資料。完成後,我們只需建立一個新物件並呼叫 fetch 方法,該方法會觸發對伺服器的非同步呼叫並使用結果填充集合。
這應該涵蓋 Backbone 集合的基礎知識。正如我所提到的,這裡有大量的好東西,其中 Backbone 別名了 Underscore 庫中的許多漂亮的實用程式。快速閱讀官方文件應該可以幫助您入門。
乍一看,Backbone 中的視圖可能會有些混亂。對於 MVC 純粹主義者來說,它們類似於控制器而不是視圖本身。
視圖從根本上處理兩項職責:
讓我們繼續建立一個非常簡單的視圖。
GameView= Backbone.View.extend({ tagName : "div", className: "game", render : function() { // code for rendering the HTML for the view } });
如果您到目前為止一直在學習本教程,那麼相當簡單。我只是透過 tagName 屬性指定應該使用哪個 HTML 元素來包裝視圖,並透過 className 指定它的 ID。
让我们继续进行渲染部分。
render : function() { this.el.innerHTML = this.model.get('name'); //Or the jQuery way $(this.el).html(this.model.get('name')); }
el 指的是视图引用的 DOM 元素。我们只是通过元素的 innerHTML 属性访问游戏的名称。简而言之,div 元素现在包含我们游戏的名称。显然,如果您以前使用过该库,则 jQuery 方式会更简单。
对于更复杂的布局,在 JavaScript 中处理 HTML 不仅乏味而且鲁莽。在这些情况下,模板是可行的方法。
Backbone 附带了由 Underscore.JS 提供的最小模板解决方案,但我们非常欢迎您使用任何可用的优秀模板解决方案。
最后我们看一下视图是如何监听事件的。首先是 DOM 事件。
events: { 'click .name': 'handleClick' }, handleClick: function(){ alert('In the name of science... you monster'); // Other actions as necessary }
如果您以前处理过事件,那么应该很简单。我们基本上是通过事件对象定义和连接事件。正如您在上面看到的,第一部分指的是事件,下一部分指定触发元素,最后一部分指应触发的函数。
现在绑定到模型和集合。我将在这里介绍模型的绑定。
GameView= Backbone.View.extend({ initialize: function (args) { _.bindAll(this, 'changeName'); this.model.bind('change:name', this.changeName); }, });
首先要注意的是我们如何将绑定代码放置在初始化函数中。当然,最好从一开始就这样做。
bindAll 是 Underscore 提供的一个实用程序,用于保存函数的 this 值。这特别有用,因为我们传递了一堆函数,并且指定为回调的函数已删除该值。
现在,只要模型的 name 属性发生更改,就会调用 changeName 函数。您还可以使用添加和删除动词来轮询更改。
侦听集合中的更改就像将处理程序绑定到回调时将模型替换为集合一样简单。
Backbone 中的控制器本质上允许您使用 hashbang 创建可添加书签的有状态应用程序。
var Hashbangs = Backbone.Controller.extend({ routes: { "!/": "root", "!/games": "games", }, root: function() { // Prep the home page and render stuff }, games: function() { // Re-render views to show a collection of books }, });
这对于传统服务器端 MVC 框架中的路由非常熟悉。例如,!/games 将映射到 games 函数,而浏览器本身中的 URL 将是 domain/#!/games。
通过智能使用 hashbang,您可以创建大量基于 JS 且可添加书签的应用程序。
如果您担心破坏后退按钮,Backbone 也能满足您的需求。
// Init the controller like so var ApplicationController = new Controller; Backbone.history.start();
通过上面的代码片段,Backbone 可以监控您的 hashbang,并结合您之前指定的路线,使您的应用程序可添加书签。
总的来说,以下是我从创建应用程序的 Backbone 方式中学到的一些经验教训:
可以说 Backbone 引起了前端构建方式的范式转变,至少对我来说是这样。鉴于今天文章的范围非常广泛,我确信您有很多问题。点击下面的评论部分来插话。非常感谢您的阅读,并期待将来有更多的 Backbone 教程!
以上是踏上 Backbone.js 之旅的詳細內容。更多資訊請關注PHP中文網其他相關文章!