前段时间,看到几篇关于各大前端开发框架的PK文章,还挺有意思:
JavaScript MVC框架PK:Angular、Backbone、CanJS与Ember
JavaScript宝座:七大框架论剑
对文章中的这句话颇有感触:
Jeremy好像进入了一种禅宗所谓的入定的状态,对一切都能坦然接受。他就像一个大人,看着一群孩子在那里辩论。
这是秒杀一切的节奏啊有没有?虽然我不是Backbone的狂热拥虿,但对于一个经常使用Backbone开发的人来说,心里还是有一些滋滋的得意的哈 :)
正好,最近在分析Backbone的源码,本着知识需要总结积累的原则,干脆就搞了一个管中窥豹
的系列,希望通过对一些亮点的分析,启发大家对Backbone的探索欲,一起来窥探Backbone的精髓。
说明:
Backbone.js版本:Development Version (1.1.0)
开发者工具:Chrome
下面进入主题:
随着移动互联网以及富客户端的兴起,应该说,SPA(Single Page Application)开发,目前进入一个迅猛发展的趋势,而个人认为,SPA的一个很重要的原则就是:RESTful。
所以,我们先来看看Model.save是怎么支持RESTful的:
Backbone的Model有一个url的参数,当我们调用save方法的时候,Backbone会根据这个地址,向服务端请求资源。所以,一般服务端那边,都会根据RESTful的原则提供好相应的服务。
所以,准确的说法,不是Backbone怎么支持RESTful,而是当服务端提供了RESTful的服务,Backbone能帮你非常方便实现请求。
接下来,我们看具体的代码,Model.save的代码在448行,在看到这里之前,我们先看一下265行:
_.extend(Model.prototype, Events, {
...
...
save: function(key, val, options) {
}
...
...
});
这样一看,大家就能更清楚的看到,save这个方法是如何成为Model的方法了吧。
然后,我们看到save的方法里面:
var attrs, method, xhr, attributes = this.attributes;
// Handle both `"key", value` and `{key: value}` -style arguments.
if (key == null || typeof key === 'object') {
attrs = key;
options = val;
} else {
(attrs = {})[key] = val;
}
看到这里的注释,它告诉我们,使用save传递参数的时候,可以这样:
someModel.save("name", "value", {wait: true})
,也可以这样someModel.save({"name": "value"}, {wait: true})
。这也是贯穿Backbone的一个原则,很多地方对hash参数的处理都是这样的,如Model.set
。
这让我想起了jQuery的CSS方法,不知道Backbone是不是受到了它的启发。
然后我的问题就出来了,如果是以后一种方式,那save
方法的参数options
,岂不就是undefined
了吗?因为方法希望接收三个参数,而实际只传入了两个参数。
这倒也没什么,但可怕的地方就在454行options = val;
,这里竟然敢这样使用options
参数,这是要闹哪样啊?
我后来试着去查,这个options
属性,到底赋给谁,我试了很多:
console.log(window.options);
console.log(someModel.options);
console.log(Backbone.options);
竟然全都是undefined
,后来,我仔细查了一下arguments
的相关知识,最后个人认为,这里的options
应该还是在这个save
方法的作用域中,就像是局部参数一样,值只在save
方法里面可用。
希望今后有哪位大神能证实一下我的想法。
然后,还有一个很巧妙的地方:
save
方法会根据{wait: true}
来判断,在save
之前,是执行Model.set
还是Model._validate
,如果validation失败了,则直接返回false
,这对保持我们业务逻辑代码的连贯性实在是太好了。
如果validation成功了,就会发起一个异步的ajax
请求,返回请求的xhr
,注意,这里的xhr
并不是要等到异步请求之后才有返回值,而是按代码执行顺序往下走,异步请求成功之后的逻辑在success
方法里面,对save
方法本身的执行顺序不造成影响。
这里面还有一些我不太明白的地方,如:
474行代码的含义;
469代码段处理的用意:this.attributes
被临时赋值之后又没使用到,为什么要临时赋值呢?
save方法就先到这里了,欢迎大家直接联系我一起讨论。