博客 / 詳情

返回

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

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

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

學習框架最好的方式就是寫一個應用出來,於是乎我就寫了一個應用來練手。中間浪費了很多很多時間在完全沒有意義的糾結上面,所以最後是花了很長時間才搞定的。

這一篇文章是一個總結,比較個人化。主要是説説收穫和經驗。

應用的功能

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

相關學習資料

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

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

模塊化

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

model和collection

backbone中,modelcollection相對於view的代碼量是小很多很多的。在裏面主要處理的是view所呈現的數據。而且比較重要的是這個model會與後端數據庫的數據類型有很密切的聯繫。一般來説,後端的接口要求“比較RESTful”,前後端以json作為數據傳遞的方式。這樣,從後端獲取數據的時候fetch到處理也比較容易,本地的數據save到服務器的數據處理也會更加自然(都是json)。當然這也不是硬性規定的,用傳統的jqueryajax也是可以的,但這可能就違背了backbone原本的初衷了(?)。在本人寫的這個應用裏面就沒有遵守這一點。後面會説明原因。

model裏面常常要覆蓋的是defaultinitialize方法,如果需要對save以及fetch的數據做特殊處理,則需要重寫toJSONparse方法。

在我的這個應用裏面,存儲的數據結構比較特殊。簡歷有幾個小的嵌套的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的比例和邊距做調整,然後確定頁面中心的區域的比例。第二個收穫就是發現淘寶的那個icon庫 iconfont 真的非常不錯,用起來也非常方便,以後可以去借一下素材hhh

遺憾

這個小應用還是有很多不足的地方

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

  2. 功能還不夠強大,如果很多內容填寫能夠更加細緻就好了...

  3. 如果要部署github的話,還不夠方便。

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

總結

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

backbone方面我還是個小白,文中有錯誤請輕噴,相互學習!謝謝大家!

代碼在這裏,希望能幫到你~

user avatar shaochuancs 頭像 suporka 頭像
2 位用戶收藏了這個故事!

發佈 評論

Some HTML is okay.