为何学习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
方面我仍是个小白,文中有错误请轻喷,相互学习!谢谢你们!
代码在这里,但愿能帮到你~