为什么要事件模型
先从 BackboneJS 开始说起。BackboneJS 设计的比较好的一部分代码就是事件相关的内容,传送门:
http://backbonejs.org/docs/backbone.html#section-13
jQuery 里面用到最多的就是bind相关的操作,为一个按钮绑定点击事件,给他解绑一个事件或者解绑所有事件,这一类的事件都是面向Dom对象。富应用中还需要一类孤立于DOM的事件,他们也需要类似添加事件、删除事件、解绑事件和触发事件。例如监测URL的变化,在其他地方可能绑定了很多事件,但是真实变化的时候只需要触发一下边能执行所有方法。
事件模型的代码
最终我自己框架里面写的事件很大部分参考了 BackboneJS ,具体代码传送门:
https://github.com/vincenting/HaiyiYun/blob/master/src/vintjs.js#L175
主要的功能包括绑定 on ,解绑 off ,触发 trigger 。on 最终期待的参数是(事件名称,回调函数,回调函数上下文),off最终期待的参数是(事件名称[,回调函数][,回调函数上下文]),trigger 最终期待的参数是(时间名称[,args…])。但是为了灵活,还需要一些灵活的参数,例如时间名称允许是多个事件名称以空格分开,以及以对象的形式同时传入名称和回调函数。于是 BackboneJS 中使用了eventsApi 进行统一的处理。
题外话-内存洁癖
Javascript 里面写[]实际上是 new Array,因此很容易无意中产生很多使用很临时的列表对象,例如一些临时列表,作为参数使用 apply 传递给函数。对于一个列表来说,最快的清空方法就是修改他的length,如下
var arr = [1,2,3,4];
arr.length = 0;
console.log(arr);
之后 arrObj 内容便会被释放。这样的对象可以多次使用,但是非临时的变量一定不能使用。原因如下:
var arr = [1,2,3,4];
var new_list = arr;
arr.length = 0;
console.log(new_list[0]);
相同的 Object 也可以运用类似的方法来重复使用。这些都是为了尽量减少对象的新建,页面一直开着什么情况都有可能发生,其他对象也是如此,字符串、函数、正则对象。
可能用到事件的地方
- 之前有提到的url变化的时候会触发事件,这些事件可能包括去寻找对应的路由并解析,对当前状态存在的事件统一解绑,删除Dom等等。
- 控制器间的通信也会用到事件模型。一个控制器中触发了一个事件,然后事件被触发去和其他控制器通信。
- 数据和视图的绑定也需要使用事件。一个数据更新了调用什么方法去更新视图,一个列表删除或者添加数据了又去调用什么方法去更新视图。
- 还有就是系统内部的解耦等等。
完成事件之后就需要去监听url的变化并且解析,以及一些类似于后台的url处理方法。(更新待续)