大家,我是阿鸵,介个是我发第一篇原创作文。废话不多说……
大家有没有设想过这样的一个Ajax请求,有一个数据,他里面呢,有一些数据可以指向其他数据,但你只需要一个函数就完成数据请求,把多个指向整合成为一个数据,介个样子你就可以直接只用,那不是很好,吼吼~~
真巧,我就基于这样的一个想法,写了这么一个东东,下面简单描述一下:
源数据是以下三个js文件(压缩文件里面也有):
data0.js:{"id":1,"code":'0x00','data1':"Ajax:data1.js"}
data1.js: {'data1':'this is data1','data2':'Ajax:data2.js'}
data2.js: {'data2':'this is data2'}
通过Ajax请求的结果为:{"id":1,"code":"0x00","data1":{"data1":"this is data1","data2":{"data2":"this is data2"}}}
这是基于Ext.Ajax实现的一个Ajax请求的一个拓展,实际上对于异步请求,请求的数据是可以满足下面的数据格式的:
data0.js:{"id":1,"code":'0x00','data1':Ajax('data1.js')}
data1.js: {'data1':'this is data1','data2':Ajax('data2.js')}
data2.js: {'data2':'this is data2'}
返回结果依然是:{"id":1,"code":"0x00","data1":{"data1":"this is data1","data2":{"data2":"this is data2"}}} ^_^
但是可能因为在调用eval函数的时候,在同步请求模式下,不能取不到正确的值,所以还是用'Ajax:data2.js',这个方式稍微妥当一点。
因为Ext的Ajax请求事件不能从中截断,加上对Ext中的事件机制不是很了解,因此这个Ajax函数和Ext的融合不是很好,事件机制是自己建立的。 (事实上,虽然Ext的Ajax请求过程中的事件不能截断,但也不是非要自己搞一个事件机制去做这样的拓展,可以把传入的success和failure的处理函数移除,待所有请求全部结束,再把success和failure的处理函数加进去,调用fireEvent,触发相应操作动作。)
欢迎大家指正!(*^_^*)
接着,我就开始贴代码了!别怪我,因为我没找到在什么地方上传文件事实上我根本不知道能不能上传文件
(Ext的版本是4.0.1,需要源码的可以邮件我,发现bug的也联系我哦……)
//Ext.Ajaxt.js
/**
*@Author ostrich
*@Email ostrich.l@foxmail.com
*@date 2011-7-15
*/
function Event(type,detail){
var me=this;
if(!(me instanceof Event))
return new Event(type,detail);
me.type=type;
if(detail)
me.detail=detail;
else
me.detail=null;
}
Event.prototype.target=null;
Event.prototype.bubble=true;
Event.prototype.cancelable=true;
Event.prototype.preventEvent=function(){
var me=this;
if(me.cancelable)
me.prevented=true;
}
Event.prototype.preventBubble=function(){
var me=this;
if(me.cancelble)
me.bubble=true;
}
Event.prototype.prevent=function(phase){
var me=this,fn='prevent'+phase;
if(me[fn]&&typeof me[fn]=='function') me[fn]();
else me.preventBubble();
};
function Ajax(options){
var me=this;
if(!(me instanceof Ajax))
return new Ajax(options);
var len=arguments.length;
if(typeof options=='string')
options={'url':options};
if(!options.url)
options.url='';
if(options.finish){
if(typeof options.finish=='function')
me.addEventListener('finish',options.finish);
options.finish=null;
delete options.finish;
}
function onSuccess(response, opts){
var result;
me.succeed++;
eval('result='+response.responseText);
me.result=result;
me.check(me.result);
me.dispatchEvent(Event('success'));
}
function onFailure(response, opts){
me.result=null;
me.converting=false;
me.failed++;
me.check();
me.dispatchEvent(Event('failure'));
}
options.success=onSuccess;
options.failure=onFailure;
me.options=options;
me.converted=false;
me.total=1;
me.succeed=0;
me.failed=0;
me.convert();
}
Ajax.prototype.addEventListener=function(type,handle){
var me=this;
me.listeners=me.listeners||{};
me.listeners[type]=me.listeners[type]||[];
me.listeners[type].push(handle);
};
Ajax.prototype.removeEventListener=function(type,handle){
var me=this;
if(!me.listeners||!me.listeners[type])
return;
var handles=me.listeners[type];
for(var i in handles){
if(handles[i]==handle){
handles.splice(i,1);
if(handles.length==0)
delete me.listeners[type];
break;
}
}
};
Ajax.prototype.hasEventListener=function(type){
var me=this;
if(!me.listeners)
return false;
return Boolean(me.listeners[type]);
}
Ajax.prototype.getEventListeners=function(type){
var me=this;
if(!me.listeners)
return false;
if(type instanceof Event)
type=type.type;
return me.listeners[type];
}
Ajax.prototype.dispatchEvent=function(e){
var me=this;
listeners=me.getEventListeners(e);
if(!listeners)
return;
if(typeof e==='string')
e=Event(e);
if(!e.target)
e.target=me;
var len=listeners.length;
for(var i=0;i<len;i++){
if(e.prevented)
break;
else if(listeners[i].call(me,e)===false)
e.preventEvent();
}
if(e.bubble&&!e.prevented&&me.parent)
me.parent.dispatchEvent(e);
};
Ajax.prototype.check=function(o){
if(arguments.length==0)
o=this;
if(o instanceof Ajax){
if(o.total>(o.succeed+o.failed))
return;
o.converting=false;
if(o.ownerDescriptor){
var owner=o.ownerDescriptor.owner;
var field=o.ownerDescriptor.field;
owner[field]=o.result;
}
o.dispatchEvent(Event('finish',{'target':o}));
return;
}
var me=this;
var count=0;
function onStatistic(e){
me.total+=e.target.total-1;
me.dispatchEvent(e);
}
function onSuccess(e){
me.succeed++;
me.check();
me.dispatchEvent(e);
}
function onFailure(e){
me.failed++;
me.check();
me.dispatchEvent(e);
}
for(var k in o){
if(typeof o[k]==='string'&&o[k].match(/^Ajax\:/g))
o[k]=Ajax({'url':o[k].replace(/^Ajax\:/g,''),'async':me.request?me.request.async:false});
if(o[k] instanceof Ajax){
if(me.request&&me.request.async){
count++;
o[k].ownerDescriptor={'owner':o,'field':k};
o[k].addEventListener('statistic',onStatistic);
o[k].addEventListener('success',onSuccess);
o[k].addEventListener('failure',onFailure);
}else{
o[k]=o[k].result;
}
continue;
}else if(typeof o[k]=='object'){
me.check(o[k]);
}
}
if(count==0)
me.check();
else{
me.total+=count;
me.dispatchEvent(Event('statistic'));
}
}
Ajax.prototype.convert=function(){
var me=this;
if(me.converted)
return me.result;
if(me.converting)
return me;
me.converting=true;
me.request=Ext.Ajax.request(me.options);
return me;
};
//Ext.Ajaxt.test.js
Ext.onReady(function(){
var ajax=Ajax({'url':'data0.js','async':true,'timeout':60000,'finish':function(e){
var s=Ext.encode(e.target.result);
document.getElementById('content').innerHTML+='<br/>'+s;
document.getElementById('content').innerHTML+='<br/>Ext.Ajax.test:finish';
}});
});