Ext.util.Event

2010年3月5日 | 分类: Extjs | 标签: ,

还就没有写关于Ext的文章了,可还是有不少人搜索Ext搜索到我的文章里来了。最近,在看Python语言和Android开发,没怎么接触Ext了,哎!真希望一天时间当两天用!

Ext.util.Event对象构建器需要传入两个对象:obj(处理事件的缺省对象),name(事件名称)。在构建Event对象时,Event对象会同时构建一个事件的处理函数的数组:listeners,通过这个数组实现了一个事件的多个事件句柄函数的处理。
Ext.util.Event = function(obj, name){
this.name = name;
this.obj = obj;
this.listeners = [];
};

通过Event的fire方法就可以依次触发该数组中的处理函数。实际上,fire方法在遍历listeners数组中的处理函数过程中,只要处理函数的返回值为false,则不再继续运行后续的处理函数。所以,可以通过检查fire方法的返回值得知事件处理函数是否完全被运行。
fire : function(){
var ls = this.listeners, scope, len = ls.length;
if(len > 0){
this.firing = true;//通过firing可以保证多个事件处理函数不会并发运行
var args = Array.prototype.slice.call(arguments, 0);//slice方法可以有效的进行数组的克隆
for(var i = 0; i < len; i++){
var l = ls;
//事件的处理,只要有一个处理函数返回false,整个事件处理就被停止
if(l.fireFn.apply(l.scope||this.obj||window, arguments) === false){
this.firing = false;
return false;
}
}
this.firing = false;
}
return true;
}

Event可以通过addListener、removeListener、clearListeners(移除所有的事件处理函数)方法对 listeners进行管理。但是,Listener中保存的事件处理函数实际上并不是addListener传递的函数,实际上,addListener传入的方法通过createListener对事件的处理函数进行了封装,通过封装,实现了对通一个重复事件的的三种不同处理方式:delay(延迟运行)、single(移除Listener中的处理函数,仅运行当前的处理函数)、buffer(避免重复运行处理函数)。

addListener : function(fn, scope, options){
var me = this,
l;
scope = scope || me.obj;
if(!me.isListening(fn, scope)){
l = me.createListener(fn, scope, options);
if(me.firing){ // if we are currently firing this event, don’t disturb the listener loop
me.listeners = me.listeners.slice(0);
}
me.listeners.push(l);
}
}

//
createListener : function(fn, scope, o){
o = o || {};
scope = scope || this.obj;
var l = {fn: fn, scope: scope, options: o};
var h = fn;
if(o.delay){
h = createDelayed(h, o, scope);
}
if(o.single){
h = createSingle(h, this, fn, scope);
}
if(o.buffer){
h = createBuffered(h, o, scope);
}
l.fireFn = h;
return l;
}

var createBuffered = function(h, o, scope){
var task = new Ext.util.DelayedTask();
return function(){
task.delay(o.buffer, h, scope, Array.prototype.slice.call(arguments, 0));
};
};
var createSingle = function(h, e, fn, scope){
return function(){
e.removeListener(fn, scope);
return h.apply(scope, arguments);
};
};
var createDelayed = function(h, o, scope){
return function(){
var args = Array.prototype.slice.call(arguments, 0);
setTimeout(function(){
h.apply(scope, args);
}, o.delay || 10);
};
};

本文的评论功能被关闭了.