基于 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方面我仍是个小白,文中有错误请轻喷,相互学习!谢谢你们!

代码在这里,但愿能帮到你~

相关文章
相关标签/搜索