backbone 之事件(code 分析)
2013-04-21 17:15 掸尘 阅读(2304) 评论(0) 编辑 收藏 举报四川地震了,表示默哀!也许你们再也不用敲代码或者为了生存而发愁。据说地震表示上天震怒了,要警示什么。我等凡夫俗子无法理解!总之,你们要坚强!
这个星期,在小组内分享了backbone的东西,想表达东西太多,结果一个也没表达清楚。不管自己的表达能力还是对backbone的理解还都还不够!backbone的自定义事件处理机制还是很强大的,翻着源码看了一下,也没弄清楚什么意思。结果看了一下backbone的单元测试,算是看明白了。所以写单元测试很有必要的。只要不是一次性的项目,在公司还是写写单元测试。不然再过几个月让你看以前项目,会陷入自己写的代码自己都不知道什么意思,那时候会骂自己怎么会写如此烂的代码!
看一下backbone的 绑定的 方法 on的代码
on: function(name, callback, context) { if (!eventsApi(this, 'on', name, [callback, context]) || !callback) return this; this._events || (this._events = {}); var events = this._events[name] || (this._events[name] = []); events.push({callback: callback, context: context, ctx: context || this}); return this; },
你会看到 eventsApi 这个方法,这个方法是干嘛的?答:用来处理绑定多个的事件的 比如你看他的测试 events.js 会有如下的代码
obj.on('a b c', function() { obj.counter += 1; }); obj.on({ a: increment, b: increment, c: increment }, obj);
第一个为是空格分割,第二个是key val的对象的形式!绑定多个事件。 如果像这样的 obj.on('event', function() { obj.counter += 1; }); 单个绑定,怎不会调用eventsApi 这个方法!看一下 eventsApi的代码
var eventsApi = function(obj, action, name, rest) { if (!name) return true; // Handle event maps. if (typeof name === 'object') { for (var key in name) { obj[action].apply(obj, [key, name[key]].concat(rest)); } return false; } // Handle space separated event names. if (eventSplitter.test(name)) { var names = name.split(eventSplitter); for (var i = 0, l = names.length; i < l; i++) { obj[action].apply(obj, [names[i]].concat(rest)); } return false; } return true; };
如果不是 空格隔开或 是对象 就返回true !个人感觉这个方法明没有表达这个方法的意思!希望Jeremy Ashkenas 重构一下建议改为 : multipleEventOn
接着看下面的代码
this._events || (this._events = {}); var events = this._events[name] || (this._events[name] = []); events.push({callback: callback, context: context, ctx: context || this});
this._events 是存储回调函数, 一个name 可能有多个事件,所以 this._events[name] 是一个数组。var events = this._events[name] || (this._events[name] = []) 这一段代码写的很好,让我写要写更多的行,作者基本功很深!
ok 以上是绑定事件源码!
off 则是除掉回调, off: function(name, callback, context) 其实就是操作 this._events, 如果只传name ,那么name下面的都会被删掉,如果传了name和callback则删掉name下面的callback!
ps:看了backbone的代码,写的挺不错!值得一看!