Truly
写精彩代码 品暇逸人生

拖了很久的文章,今天终于着手开始撰写了。时间比较仓促,写的乱七八糟,有空我在整理一下,这里先贴一个预览版本,算是给自己一个交待。本文主要分析AjaxPro客户端类库的3个JS文件:



prototype.ashx

大家知道,JavaScript是一种原型驱动的语言,所以要扩展JavaScript语言,就必须从prototype入手,为JavaScript的Function,Object对象进行扩展。
本文重点是分析AjaxPro中的prototype应用,但是必须要简单介绍一下prototype:

通过prototpe我们可以为对象增加一些“实例方法”(姑且这么叫吧,下同),请看下面代码,注意Test和Test2方法定义和使用的差别。 

<script>
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客户端类库的底层的公用方法,用来为任何对象(函数、对象)增加或替换其属性和方法。
代码如下:

Object.extend = function(dest, source, replace) {
    
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浏览器。

<script>
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>

(未完待更新)

posted on 2007-01-12 17:52  Truly  阅读(5228)  评论(10编辑  收藏  举报