Backbone事件Events
2015-11-28 20:42
387 查看
说道Backbone的事件机制。自己也是逗逼了。敲了一遍Backbone的源码。。居然是还不知道他的机制。。
先上Events On对象的源码
先上Events On对象的源码
/** * Created by More on 2015/11/28. */ var Events = Backbone.Events ={ /** * params: * events : 事件们 * callback : 回调函数 * context : 上下文,俗称的this * * **/ on: function(events,callback,context){ var calls,//回调函数数字 event,//切割的事件名称 node,//节点对象 tail,//节点的结尾,用于判断所有回调是否执行完毕 list;//保存当前对象中的事件对象 if(!callback){ return this; } //事件切割数组 events = events.split(eventSplitter); //回调对象 calls = this._callbacks || (this._callbacks = {}); while(event = events.shift()){ list = calls[event]; node = list ? list.tail : {}; node.next = tail = {}; node.context = context; calls[event] ={ tail : tail, next : list ? list.next : node } } return this; } } 一开始,我都不知道原理是啥,只知道他丢进去了一个_CallBacks对象在Backbone里边,里边的键值对是有序的,包括回调函数都是有序的保存在该对象中,但是不知道是怎么触发的。。 老老实实又去看了下collection的原型,再上源码
add : function(models, options) { // 局部变量定义 var i, index, length, model, cid, id, cids = {}, ids = {}, dups = []; options || ( options = {}); // models必须是一个数组, 如果只传入了一个模型, 则将其转换为数组 models = _.isArray(models) ? models.slice() : [models]; // 遍历需要添加的模型列表, 遍历过程中, 将执行以下操作: // - 将数据对象转化模型对象 // - 建立模型与集合之间的引用 // - 记录无效和重复的模型, 并在后面进行过滤 for( i = 0, length = models.length; i < length; i++) { // 将数据对象转换为模型对象, 简历模型与集合的引用, 并存储到model(同时models中对应的模型已经被替换为模型对象) if(!( model = models[i] = this._prepareModel(models[i], options))) { throw new Error("Can't add an invalid model to a collection"); } // 当前模型的cid和id cid = model.cid; id = model.id; // dups数组中记录了无效或重复的模型索引(models数组中的索引), 并在下一步进行过滤删除 // 如果cids, ids变量中已经存在了该模型的索引, 则认为是同一个模型在传入的models数组中声明了多次 // 如果_byCid, _byId对象中已经存在了该模型的索引, 则认为同一个模型在当前集合中已经存在 // 对于上述两种情况, 将模型的索引记录到dups进行过滤删除 if(cids[cid] || this._byCid[cid] || ((id != null) && (ids[id] || this._byId[id]))) { dups.push(i); continue; } // 将models中已经遍历过的模型记录下来, 用于在下一次循环时进行重复检查 cids[cid] = ids[id] = model; } // 从models中删除无效或重复的模型, 保留目前集合中真正需要添加的模型列表 i = dups.length; while(i--) { models.splice(dups[i], 1); } // 遍历需要添加的模型, 监听模型事件并记录_byCid, _byId列表, 用于在调用get和getByCid方法时作为索引 for( i = 0, length = models.length; i < length; i++) { // 监听模型中的所有事件, 并执行_onModelEvent方法 // _onModelEvent方法中会对模型抛出的add, remove, destroy和change事件进行处理, 以便模型与集合中的状态保持同步 ( model = models[i]).on('all', this._onModelEvent, this); // 将模型根据cid记录到_byCid对象, 便于根据cid进行查找 this._byCid[model.cid] = model; // 将模型根据id记录到_byId对象, 便于根据id进行查找 if(model.id != null) this._byId[model.id] = model; } // 改变集合的length属性, length属性记录了当前集合中模型的数量 this.length += length; // 设置新模型列表插入到集合中的位置, 如果在options中设置了at参数, 则在集合的at位置插入 // 默认将插入到集合的末尾 // 如果设置了comparator自定义排序方法, 则设置at后还将按照comparator中的方法进行排序, 因此最终的顺序可能并非在at指定的位置 index = options.at != null ? options.at : this.models.length; splice.apply(this.models, [index, 0].concat(models)); // 如果设置了comparator方法, 则将数据按照comparator中的算法进行排序 // 自动排序使用silent属性阻止触发reset事件 if(this.comparator) this.sort({ silent : true }); // 依次对每个模型对象触发"add"事件, 如果设置了silent属性, 则阻止事件触发 if(options.silent) return this; // 遍历新增加的模型列表 for( i = 0, length = this.models.length; i < length; i++) { if(!cids[( model = this.models[i]).cid]) continue; options.index = i; // 触发模型的"add"事件, 因为集合监听了模型的"all"事件, 因此在_onModelEvent方法中, 集合也将触发"add"事件 // 详细信息可参考Collection.prototype._onModelEvent方法 model.trigger('add', model, this, options); } return this; }, 原来在这里的最后几行代码中,手动触发了这个事件,导致自定义的事件可以被触发。。差点就被自己给坑进去了。。还以为自己发现了什么心技能。。可以隐式的定义方法在对象的_callBacks对象中。。 呀呀呀。。继续干。。
相关文章推荐
- html基础代码使用
- 126.Oracle数据库SQL开发之 数据库对象——PLSQL中使用对象
- Android Studio编译大工程报错:java.exe'' finished with non-zero exit value 1 or exit value 2
- PRML 课后题答案 第一章 1.1
- JAVA中的容器
- ORA-12514 TNS 监听程序当前无法识别连接描述符中请求服务
- 简单JNI编程实现
- Jira和confluence关联
- 125.Oracle数据库SQL开发之 数据库对象——数据库中使用对象类型
- Oracle数据库基础
- JVM内存区域划分Eden Space、Survivor Space、Tenured Gen,Perm Gen解释
- [MyBatis]MyBatis出现的问题
- 【读书笔记】:网络安全复习
- 1022. D进制的A+B (20)
- 简易文本爬虫
- app上线流程
- Spring Bean组件实现和源码分析
- HDU 1003 Max Sum
- Sum-(最大子序列和)
- 124.Oracle数据库SQL开发之 数据库对象——查看对象类型