爲何學習backbone
?這是個好問題。在這個前端框架爆炸的年代,比起backbone
,對開發來講有更多更好的選擇,react
,vue
,angular
等等。但這些在使用這些框架的時候,內心卻老是有寫不踏實的感受。MVVM
雙向綁定是怎麼實現的?Virtual DOM
,diff
算法在react
裏面是怎麼實現的?大框架很差的地方就是,對於新手來講,真正認識其中的原理很不容易。原理不會變,而API
是會變的。css
因此我決定靜下心先學習backbone
,並認真地研究其中的原理。(這裏挖一個坑。這幾天在讀backbone
和underscore
的源碼,爭取寫一篇源碼解析的文章。)html
學習框架最好的方式就是寫一個應用出來,因而乎我就寫了一個應用來練手。中間浪費了不少不少時間在徹底沒有意義的糾結上面,因此最後是花了很長時間才搞定的。前端
這一篇文章是一個總結,比較我的化。主要是說說收穫和經驗。vue
這個應用是一個我的簡歷生成器。前端用backbone
+ jquery
+ underscore
+ webpack
+ scss
,後端用express
。能夠經過瀏覽器界面填寫我的相關信息,把數據發送到後端,用nodejs
來負責存儲數據,生成靜態文件。具體詳情能夠見github
的地址。node
backbone
屬於典型的,學的時候以爲很簡單,本身寫的時候一臉懵逼的框架。相比react
,react
學的時候以爲難度不小,並且加上redux
以後對一些函數式編程的東西偶爾會感到很費解。但是跟着redux
官網推薦的教程慢慢看以後仍是可以比較輕鬆地寫出一個過得去的應用的。然而backbone確是相反,學的時候以爲不難,真正寫的時候卻感受不少東西很難控制,並且要思考的地方比用大框架多很多。react
比較好的教程有這一個。這個教程裏面講了mvc
的基礎知識,backbone
的基礎知識,以及一個todo
應用,一個帶後端的應用還有一個和用requirejs
進行模塊化處理的應用。根據這個教程老老實實過一遍其實大體就差很少了(然而我只看了todo
...)。可是要深刻理解並用backbone
寫大應用仍是有不小難度的。jquery
這裏用了webpack
。說實話,webpack
真的是神通常的存在。AMD
也好,CMD
也好,ES6
模塊化標準也好均可以輕鬆打包壓縮,還有不少很方便的插件,不能再爽...backbone
的年代(說的好像好久遠了同樣...)可能模塊化還不算特別普及,因此不少例子也是用script
引入的。這樣的命名污染問題天然顯而易見。並且發出屢次請求也會影響性能。所以經過模塊化打包仍是很是必要的。webpack
在backbone
中,model
和collection
相對於view的代碼量是小不少不少的。在裏面主要處理的是view
所呈現的數據。並且比較重要的是這個model
會與後端數據庫的數據類型有很密切的聯繫。通常來講,後端的接口要求「比較RESTful
」,先後端以json
做爲數據傳遞的方式。這樣,從後端獲取數據的時候fetch處處理也比較容易,本地的數據save
到服務器的數據處理也會更加天然(都是json
)。固然這也不是硬性規定的,用傳統的jquery
的ajax
也是能夠的,但這可能就違背了backbone
本來的初衷了(?)。在本人寫的這個應用裏面就沒有遵照這一點。後面會說明緣由。git
model
裏面經常要覆蓋的是default
,initialize
方法,若是須要對save
以及fetch
的數據作特殊處理,則須要重寫toJSON
和parse
方法。github
在個人這個應用裏面,存儲的數據結構比較特殊。簡歷有幾個小的嵌套的collection
,有幾個不是collection
的attributes
,算是比較複雜的結構。所以重寫了toJSON
和parse
方法,可是後來沒有用到重寫的parse
方法,由於發現直接用jquery
的ajax
更加方便直接。重寫的方法見這個連接,具體來講就是當須要保存並post
數據到數據庫的時候,把model
的屬性(這個屬性不是attributes
裏面的那個,而是真正意義上的屬性,相似a.b
)解析爲json
結構,而後再保存。而fetch到數據的時候就用獲得的數據(通常是json
)初始化幾個collection
,而後直接加到model
的屬性(a.b
這種形式的屬性)中去。
。其實這種狀況應該是用backbone-relational
之類的庫來解決的,但能解決問題就好。
在view
中,collection
和model
會根據用戶操做view
而發生變化,而變化以後又會影響view
的數據呈現。而關於model
和collection
的其餘操做還有一些增刪查改之類的能夠在具體狀況下使用。這些操做也是經常寫在view
中的。
view
是一個大塊頭,這個應用中view
佔了代碼中最大的部分。
view
,顧名思義,就是視圖,數據的呈現。這裏經常和模板配合。在寫後端express
應用的時候,由於ejs
有include
的功能,所以模板就被切成了一小塊一小塊,這樣能夠避免html
主文件過大。可是backbone
的不少例子都是直接一大塊一大塊地把模板塞到html
主文件裏面。明顯不利於維護。所以參考了別人的代碼,寫了下面的輔助函數,把視圖的html
文件讀取進來,並添加到相應的view的模板裏面,所有讀取完以後就調用回調函數。代碼以下:
var loadTemplate = function(views, callback) { var deferreds = []; $.each(views, function(index, view) { if(require('./views/' + view)) { // 把異步事件,即從文件中讀取html文件的函數,壓入deferreds中 deferreds.push($.get('../tpl/' + view + '.html', function(data) { // 修改相應的view的template require('./views/' + view).prototype.template = _.template(data); })); } else { alert(view + " not found"); } }); // 把全部異步操做都完成以後才調用callback $.when.apply(null, deferreds).done(callback); }
用這種方法來處理html
過大問題不算最好的方法,可是在這裏可以很好地解決問題。
在view
中主要的是events
,render
,initialize
。在initialize
裏面能夠經過listenT
o來監聽一些model
事件。
有時候在寫initialize
的時候要本身render
,但不少狀況下不須要。render
函數裏面返回this
以後,能夠在其餘地方,好比router
中把model
注入模板中而後把render
返回的html
直接插入頁面中。
var view = new formView({}); this.$container.html(view.render().el);
backbone
的路由功能很是方便。在個人app
應用裏面整個程序的入口就是router
的函數。能夠經過不一樣的url
綁定不一樣的函數,在函數中調用視圖的函數來實現不一樣路由的不一樣的html
片斷。
然而在實際操做的時候,多是由於我的能力還不夠,有一個困難從頭至尾都沒法解決。後來用了比較很差的辦法勉強替代了。問題以下:假如要定義路由'/:tab/:filename'
,每次路由發生改變的時候都會調用路由函數。若是在這個路由函數裏我新建了一個model
實例,那當我想改變tab
的時候,就不得不從新觸發路由函數,從新新建model
。然而我但願model
可以不發生變化,由於tab
是在filename
文件的前提下的標籤頁,不能換一個標籤就重建一個model
。這樣作要如何實現呢?想了三天到最後我仍是放棄了...(也有可能本身想的需求是有點奇葩..)
原來直接window.print()
就能夠調用瀏覽器打印功能了呀。有個小收穫就是有關瀏覽器打印的尺寸問題,要根據A4
的比例和邊距作調整,而後肯定頁面中心的區域的比例。第二個收穫就是發現淘寶的那個icon
庫 iconfont 真的很是不錯,用起來也很是方便,之後能夠去借一下素材hhh
這個小應用仍是有不少不足的地方
UI
不足,簡歷頁面設計不足。(想爆了腦殼都不知怎麼搞比較好看...)
功能還不夠強大,若是不少內容填寫可以更加細緻就行了...
若是要部署github
的話,還不夠方便。
node
裏面生成頁面那裏用了一些拼接字符串的方法,更加不是很優雅...
經過這個backbone
應用的編寫,對於backbone
算是有一個初步的瞭解了吧。對於MVC
框架也有了一個大致的認識。最近在看backbone
和underscore
的源碼,明後天會開始寫一篇源碼解讀的文章,總結一下backbone
裏面值得學習的地方。(如今還在看,以爲history
裏面對於瀏覽器兼容的考慮處理挺有意思,Events
要看點設計模式的東西)。這個暑假的最後就慢慢地看多幾遍backbone
,好好學習一個!
在backbone
方面我仍是個小白,文中有錯誤請輕噴,相互學習!謝謝你們!
代碼在這裏,但願能幫到你~