[轉]Backbone.js簡單入門范例


本文轉自:http://dmyz.org/archives/598

11年剛開始用前端MVC框架時寫過一篇文章,當時Knockout和Backbone都在用,但之后的項目全是在用Backbone,主要因為它簡單、靈活,無論是富JS應用還是企業網站都用得上。寫這篇文章的動機,是最近跟做在線教育的朋友聊,談到比較好的中文入門教程不多,於是想針對自己用得最多的框架寫一篇,說明如下:

1. 結構上分4節,介紹Model/View/Collection,實現從遠程獲取數據顯示到表格且修改刪除; 2. 名為“范例”,所以代碼為主,每節的第1段代碼都是完整代碼,復制粘貼就能用,每段代碼都是基於前一段代碼來寫的,因此每段代碼的新內容不會超過20行(大括號計算在內); 3. 每行代碼沒有注釋,但重要內容之后有寫具體的說明; 4. 開發環境是Chrome,使用github的API,這樣用Chrome即使在本地路徑(形如file://的路徑)也能獲取數據。

0. Introduction

幾乎所有的框架都是在做兩件事:一是幫你把代碼寫在正確的地方;二是幫你做一些臟活累活。Backbone實現一種清晰的MVC代碼結構,解決了數據模型和視圖映射的問題。雖然所有JS相關的項目都可以用,但Backbone最適合的還是這樣一種場景:需要用JS生成大量的頁面內容(HTML為主),用戶跟頁面元素有很多的交互行為。

Backbone對象有5個重要的函數,Model/Collection/View/Router/History。Router和History是針對Web應用程序的優化,建議先熟悉pushState的相關知識。入門階段可以只了解Model/Collection/View。將Model視為核心,Collection是Model的集合,View是為了實現Model的改動在前端的反映。

 

1. Model

Model是所有JS應用的核心,很多Backbone教程喜歡從View開始講,其實View的內容不多,而且理解了View意義不大,理解Model更重要。以下代碼實現從github的API獲取一條gist信息,顯示到頁面上:

 

  • LINE4~8: 加載要用到的JS庫。ajax請求和部分View的功能需要jQuery支持(或者重寫ajax/View的功能);Backbone的代碼是基於Underscore寫的(或者用Lo-Dash代替);加載bootstrap.css只是因為默認樣式太難看…
  • LINE16~22: 創建一個Model並實例化。url是數據源(API接口)的地址,parse用來處理返回的數據。實際返回的是一個Array,這里取第一個Object。
  • LINE24~33: 綁定change事件。還沒有使用View,所以要自己處理HTML。這10行代碼主要是get的用法(model.get),其他的功能之后會用View來實現。
  • LINE34: 執行fetch。從遠程獲取數據,獲到數據后會觸發change事件。可以重寫sync方法

打開Chrome的Console,輸入gist,可以看到Model獲得的屬性: backbone_model_attrs

Model提供數據和與數據相關的邏輯。上圖輸出的屬性是數據,代碼中的fetch/parse/get/set都是對數據進行操作,其他的還有escape/unset/clear/destory,從函數名字就大致可以明白它的用途。還有很常用的validate函數,在set/save操作時用來做數據驗證,驗證失敗會觸發invalid事件:

 

 

跟之前的代碼比較,有4處改動:

  • LINE7~9: 增加了defaults。如果屬性中沒有website(注意不是website值為空),會設置website值為dmyz。
  • LINE10~14: 增加validate函數。當website值為dmyz時,觸發invalid事件。
  • LINE18~20: 綁定invalid事件,alert返回的錯誤。
  • LINE31: 不做fetch,直接save操作。

因為沒有fetch,所以頁面上不會顯示數據。執行save操作,會調用validate函數,驗證失敗會觸發invalid事件,alert出錯誤提示。同時save操作也會向Model的URL發起一個PUT請求,github這個API沒有處理PUT,所以會返回404錯誤。

在Console中輸入gist.set(‘description’, ‘demo’),可以看到頁面元素也會有相應的變化。執行gist.set(‘description’, gist.previous(‘description’))恢復之前的值。這就是Model和View的映射,現在還是自己實現的,下一節會用Backbone的View來實現。

2. View

用Backbone的View來改寫之前代碼LINE24~33部分:

 

  • LINE25: 所有的View都是基於DOM的,指定el會選擇頁面的元素,指定tagName會創建相應的DOM,如果都沒有指定會是一個空的div。
  • LINE27~32: 綁定click事件到a標簽,replaceURL函數會修改(set)url屬性的值。
  • LINE33~35: View的初始化函數(initialize),監聽change事件,當Model數據更新時觸發render函數。
  • LINE36~42: render函數。主要是LINE41~42這兩行,把生成的HTML代碼寫到this.el,返回this。
  • LINE44: 實例化GistRow,初始化函數(initialize)會被執行。

點擊行末的a標簽,頁面顯示的這條記錄的URL會被修改成http://dmyz.org。

這個View名為GistRow,選擇的卻是tbody標簽,這顯然是不合理的。接下來更改JS代碼,顯示API返回的30條數據:

 

 

  • LINE2~9: 創建了兩個Model(Gist和Gists),parse現在返回完整Array而不只是第一條。
  • LINE11~18: 創建一個tr。render方法會傳一個Object來實例化一個Gist的Model,再從這個Model里get需要的值。
  • LINE26~34: 遍歷Model中的所有屬性。現在使用的是Model而不是Collection,所以遍歷出的是Object。forEach是Underscore的函數。

Backbone的View更多的是組織代碼的作用,它實際干的活很少。View的model屬性在本節第一段代碼用的是大寫,表明只是一個名字,並不是說給View傳一個Model它會替你完成什么,控制邏輯還是要自己寫。還有View中經常會用到的template函數,也是要自己定義的,具體結合哪種模板引擎來用就看自己的需求了。

這段代碼中的Gists比較難操作其中的每一個值,它其實應該是Gist的集合,這就是Backbone的Collection做的事了。

3. Collection

Collection是Model的集合,在這個Collection中的Model如果觸發了某個事件,可以在Collection中接收到並做處理。第2節的代碼用Collection實現:

 

 

  • LINE17~23: 基本跟第2節的第2段代碼一樣。把Model改成Collection,指定Collection的Model,這樣Collectio獲得返回值會自動封裝成Model的Array。
  • LINE38: Collection和Model不同,獲取到數據也不會觸發事件,所以綁定一個reset事件,在之后的fetch操作中傳遞{reset: true}。
  • LINE42~45: 從Collection從遍歷Model,傳給GistRow這個View,生成HTML。

Collection是Backbone里功能最多的函數(雖然其中很多是Underscore的),而且只要理解了Model和View的關系,使用Collection不會有任何障礙。給Collection綁定各種事件來實現豐富的交互功能了,以下這段JS代碼會加入刪除/編輯的操作,可以在JSBIN上查看源代碼和執行結果。只是增加了事件,沒有什么新內容,所以就不做說明了,附上JSBIN的演示地址:http://jsbin.com/jevisopo/1

 

 

Afterword

雖然是入門范例,但因為篇幅有限,有些基本語言特征和Backbone的功能不可能面面俱到,如果還看不懂肯定是我漏掉了需要解釋的點,請(在Google之后)評論或是郵件告知。

Backbone不是jQuery插件,引入以后整個DOM立即實現增刪改查了,也做不到KnockoutJS/AnglarJS那樣,在DOM上做數據綁定就自動完成邏輯。它是將一些前端工作處理得更好更規范,如果學習前端MVC的目的是想輕松完成工作,Backbone可能不是最佳選擇。如果有一個項目,100多行HTML和1000多行JS,JS主要都在操作頁面DOM,那就可以考慮用Backbone來重寫了。它比其他龐大的MVC框架要容易掌握得多,作為入門學習也是非常不錯的。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM