基於 Backbone + node 的我的簡歷生成器(我的學習總結)

爲何學習backbone?這是個好問題。在這個前端框架爆炸的年代,比起backbone,對開發來講有更多更好的選擇,reactvueangular等等。但這些在使用這些框架的時候,內心卻老是有寫不踏實的感受。MVVM雙向綁定是怎麼實現的?Virtual DOMdiff算法在react裏面是怎麼實現的?大框架很差的地方就是,對於新手來講,真正認識其中的原理很不容易。原理不會變,而API是會變的。css

因此我決定靜下心先學習backbone,並認真地研究其中的原理。(這裏挖一個坑。這幾天在讀backboneunderscore的源碼,爭取寫一篇源碼解析的文章。)html

學習框架最好的方式就是寫一個應用出來,因而乎我就寫了一個應用來練手。中間浪費了不少不少時間在徹底沒有意義的糾結上面,因此最後是花了很長時間才搞定的。前端

這一篇文章是一個總結,比較我的化。主要是說說收穫和經驗。vue

應用的功能

這個應用是一個我的簡歷生成器。前端用backbone + jquery + underscore + webpack + scss,後端用express。能夠經過瀏覽器界面填寫我的相關信息,把數據發送到後端,用nodejs來負責存儲數據,生成靜態文件。具體詳情能夠見github地址node

相關學習資料

backbone屬於典型的,學的時候以爲很簡單,本身寫的時候一臉懵逼的框架。相比reactreact學的時候以爲難度不小,並且加上redux以後對一些函數式編程的東西偶爾會感到很費解。但是跟着redux官網推薦的教程慢慢看以後仍是可以比較輕鬆地寫出一個過得去的應用的。然而backbone確是相反,學的時候以爲不難,真正寫的時候卻感受不少東西很難控制,並且要思考的地方比用大框架多很多。react

比較好的教程有這一個。這個教程裏面講了mvc的基礎知識,backbone的基礎知識,以及一個todo應用,一個帶後端的應用還有一個和用requirejs進行模塊化處理的應用。根據這個教程老老實實過一遍其實大體就差很少了(然而我只看了todo...)。可是要深刻理解並用backbone寫大應用仍是有不小難度的。jquery

模塊化

這裏用了webpack。說實話,webpack真的是神通常的存在。AMD也好,CMD也好,ES6模塊化標準也好均可以輕鬆打包壓縮,還有不少很方便的插件,不能再爽...backbone的年代(說的好像好久遠了同樣...)可能模塊化還不算特別普及,因此不少例子也是用script引入的。這樣的命名污染問題天然顯而易見。並且發出屢次請求也會影響性能。所以經過模塊化打包仍是很是必要的。webpack

model和collection

backbone中,modelcollection相對於view的代碼量是小不少不少的。在裏面主要處理的是view所呈現的數據。並且比較重要的是這個model會與後端數據庫的數據類型有很密切的聯繫。通常來講,後端的接口要求「比較RESTful」,先後端以json做爲數據傳遞的方式。這樣,從後端獲取數據的時候fetch處處理也比較容易,本地的數據save到服務器的數據處理也會更加天然(都是json)。固然這也不是硬性規定的,用傳統的jqueryajax也是能夠的,但這可能就違背了backbone本來的初衷了(?)。在本人寫的這個應用裏面就沒有遵照這一點。後面會說明緣由。git

model裏面經常要覆蓋的是defaultinitialize方法,若是須要對save以及fetch的數據作特殊處理,則須要重寫toJSONparse方法。github

在個人這個應用裏面,存儲的數據結構比較特殊。簡歷有幾個小的嵌套的collection,有幾個不是collectionattributes,算是比較複雜的結構。所以重寫了toJSONparse方法,可是後來沒有用到重寫的parse方法,由於發現直接用jqueryajax更加方便直接。重寫的方法見這個連接,具體來講就是當須要保存並post數據到數據庫的時候,把model的屬性(這個屬性不是attributes裏面的那個,而是真正意義上的屬性,相似a.b)解析爲json結構,而後再保存。而fetch到數據的時候就用獲得的數據(通常是json)初始化幾個collection,而後直接加到model的屬性(a.b這種形式的屬性)中去。

。其實這種狀況應該是用backbone-relational之類的庫來解決的,但能解決問題就好。
view中,collectionmodel會根據用戶操做view而發生變化,而變化以後又會影響view的數據呈現。而關於modelcollection的其餘操做還有一些增刪查改之類的能夠在具體狀況下使用。這些操做也是經常寫在view中的。

view

view是一個大塊頭,這個應用中view佔了代碼中最大的部分。

view,顧名思義,就是視圖,數據的呈現。這裏經常和模板配合。在寫後端express應用的時候,由於ejsinclude的功能,所以模板就被切成了一小塊一小塊,這樣能夠避免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中主要的是eventsrenderinitialize。在initialize裏面能夠經過listenTo來監聽一些model事件。

有時候在寫initialize的時候要本身render,但不少狀況下不須要。render函數裏面返回this以後,能夠在其餘地方,好比router中把model注入模板中而後把render返回的html直接插入頁面中。

var view = new formView({});
this.$container.html(view.render().el);

router

backbone的路由功能很是方便。在個人app應用裏面整個程序的入口就是router的函數。能夠經過不一樣的url綁定不一樣的函數,在函數中調用視圖的函數來實現不一樣路由的不一樣的html片斷。
然而在實際操做的時候,多是由於我的能力還不夠,有一個困難從頭至尾都沒法解決。後來用了比較很差的辦法勉強替代了。問題以下:假如要定義路由'/:tab/:filename',每次路由發生改變的時候都會調用路由函數。若是在這個路由函數裏我新建了一個model實例,那當我想改變tab的時候,就不得不從新觸發路由函數,從新新建model。然而我但願model可以不發生變化,由於tab是在filename文件的前提下的標籤頁,不能換一個標籤就重建一個model。這樣作要如何實現呢?想了三天到最後我仍是放棄了...(也有可能本身想的需求是有點奇葩..)

其餘小收穫

原來直接window.print()就能夠調用瀏覽器打印功能了呀。有個小收穫就是有關瀏覽器打印的尺寸問題,要根據A4的比例和邊距作調整,而後肯定頁面中心的區域的比例。第二個收穫就是發現淘寶的那個iconiconfont 真的很是不錯,用起來也很是方便,之後能夠去借一下素材hhh

遺憾

這個小應用仍是有不少不足的地方

  1. UI不足,簡歷頁面設計不足。(想爆了腦殼都不知怎麼搞比較好看...)

  2. 功能還不夠強大,若是不少內容填寫可以更加細緻就行了...

  3. 若是要部署github的話,還不夠方便。

  4. node裏面生成頁面那裏用了一些拼接字符串的方法,更加不是很優雅...

總結

經過這個backbone應用的編寫,對於backbone算是有一個初步的瞭解了吧。對於MVC框架也有了一個大致的認識。最近在看backboneunderscore的源碼,明後天會開始寫一篇源碼解讀的文章,總結一下backbone裏面值得學習的地方。(如今還在看,以爲history裏面對於瀏覽器兼容的考慮處理挺有意思,Events要看點設計模式的東西)。這個暑假的最後就慢慢地看多幾遍backbone,好好學習一個!

backbone方面我仍是個小白,文中有錯誤請輕噴,相互學習!謝謝你們!

代碼在這裏,但願能幫到你~

相關文章
相關標籤/搜索