拖了很久的文章,今天终于着手开始撰写了。时间比较仓促,写的乱七八糟,有空我在整理一下,这里先贴一个预览版本,算是给自己一个交待。本文主要分析AjaxPro客户端类库的3个JS文件:
prototype.ashx
大家知道,JavaScript是一种原型驱动的语言,所以要扩展JavaScript语言,就必须从prototype入手,为JavaScript的Function,Object对象进行扩展。
本文重点是分析AjaxPro中的prototype应用,但是必须要简单介绍一下prototype:
通过prototpe我们可以为对象增加一些“实例方法”(姑且这么叫吧,下同),请看下面代码,注意Test和Test2方法定义和使用的差别。
String.prototype.Test = function(s){return s;};// 定义实例方法
String.Test2 = function(s){return s;};// 定义静态方法
var str1 = "Truly";
alert(typeof str1.Test + "\n" + //function, 实例引用
typeof str1.Test2 + "\n" + //undefined,实例引用
typeof String.Test + "\n" + //undefined,静态引用
typeof String.Test2); //function,静态引用
alert(str1.Test("实例调用")); //实例方法正确调用
alert(String.Test2("静态调用")); //静态方法正确调用
</script>
prototype的具体工作原理超出了本文讨论范围,感兴趣的请使用Google进行搜索查阅。
接下来我们开始分析第一个文件prototype.ashx,可以通过IE中使用http://localhost/ajaxpro/prototype.ashx打开并将其保存下来,或者是AjaxPro源码中的prototype.js文件,用文本编辑器或者VS之类的开发工具打开,可以看到这个文件中首先为Object定义了一个extend方法,它是AjaxPro客户端类库的底层的公用方法,用来为任何对象(函数、对象)增加或替换其属性和方法。
代码如下:
for(var prop in source) {
if(replace == false && dest[prop] != null) { continue; }
dest[prop] = source[prop];
}
return dest;
};
继续阅读源码,发现接下来的代码分别使用extend方法扩展了Function、Array、String等JavaScript对象的实例方法和静态方法。
首先是通过原型模式为Function增加了bind方法,并覆盖了JavaScript内置的apply方法,这样包含了prototype.ashx的页面上所有的函数都具有了bind方法和新的apply方法。
注意:apply原是JavaScript的一个内置方法,它的作用是应用某一对象的一个方法,用另一个对象替换当前对象。
core.ashx
core.ashx,顾名思义,它是AjaxPro的核心,主要定义了AjaxPro客户端类型并提供了一些操作方法。
与前面prototype.ashx一样,我们使用编辑器或者开发工具打开,core.ashx源码中首先为Function通过原型方式增加了getArguments实例方法。
为了更好的了解这个重要方法,首先我们要了解一下JavaScript中的arguments 对象:
arguments:它是function的一个属性,为当前执行的 function 对象返回一个arguments 对象。通过 arguments 属性,函数可以处理可变数量的参数。 arguments 对象的 length 属性包含了传递给函数的参数的数目。对于arguments 对象所包含的单个参数,其访问方法与数组中所包含的参数的访问方法相同。
而这里定义的getArguments方法就是用来把当前执行的function对象的arguments属性转换为一个数组返回。
在core.ashx中扩展了getArguments方法后,它又定义了一个MS对象,其中包括了一个子对象Browser,并具有3个静态属性,用来指示当前客户端的浏览器。比如我们可以使用下面代码来判断客户机是否是IE浏览器。
if(MS.Browser.isIE)
alert('You use a IE browser.');
</script>
接下来就是AjaxPro对象的定义,同样的在AjaxPro对象下面又定义了很多子对象及其方法和属性,见下表,暂未整理完成
名称 | 类型 | 说明 |
IFrameXmlHttp | ||
noOperation | ||
onLoading | ||
onError | ||
onTimeout | ||
onStateChanged | ||
queue | ||
toJSON | ||
dispose | ||
Request | ||
RequestQueue | ||
AjaxClass | 含有invoke实例方法和url静态属性 | |
cryptProvider | ||
token | ||
version | ||
ID | ||
noActiveX | ||
timeoutPeriod |
这里面最终要的核心函数就是IFrameXmlHttp,它是整个异步操作最终与服务器交互的地方。
coverter.ashx
converter.ashx的作用是将.NET的一些类型映射为客户端类型,一共有5个类型转换,分别是
- NameValueCollectionConverter
- DataSetConverter
- DataTableConverter
- ProfileBaseConverter
- IDictionaryConverter
/*
// NameValueCollectionConverter
将.Net类库中的System.Collections.Specialized.NameValueCollection映射为Ajax.Web.NameValueCollection
定义了一个客户端的键值集合类(Ajax.Web.NameValueCollection),具有add,containsKey,getKeys,getValue,setValue,toJSON实例方法成员
字段属性包括__type,keys,values。分别返回类型字符串,键集合,和值集合。
// DataSetConverter
System.Data.DataSet,System.Data
定义了一个客户端的DataSet集合类(Ajax.Web.DataSet),具有addTable实例方法成员
字段属性包括__type,Tables。分别返回类型字符串,表集合。
// DataTableConverter
System.Data.DataTable,System.Data
定义了一个客户端的DataTable集合类(Ajax.Web.DataTable),具有addColumn,toJSON,addRow实例方法成员
字段属性包括__type,Columns,Rows。分别返回类型字符串,列集合和行集合。
// ProfileBaseConverter
定义了Ajax.Web.Profile类
成员如下
字段:
方法:setProperty_callback,setProperty
// IDictionaryConverter
Ajax.Web.Dictionary类
成员如下
字段:__type,keys,values。分别返回类型字符串,键集合,和值集合。
方法:add,containsKey,getKeys,getValue,setValue,toJSON
*/
----------------------------------------------------
onloading demo
<script type="text/javascript" defer="defer">
var c = 0;
AjaxPro.onLoading = function(b) {
c++;
window.status = c;
var l = document.getElementById("loadinfo");
l.style.visibility = b ? "visible" : "hidden";
}
function doTest1() {
c = 0;
ASP.LoadingDemo.LongOperation(doTest1_callback);
}
function doTest1_callback(res) {
alert(res.value);
}
</script>
(未完待更新)