Ext中Ajax技术详解

Ajax技术的核心是XMLHttpRequest对象。原生JavaScript实现Ajax的流程为:创建XHR对象实例,实例使用open()方法(设定发送请求类型、URL以及是否异步),然后使用send()方法传送相应数据,即完成请求。接下来,通过检查xhr实例的状态,判断是否返回所需值,并对response进行解析,执行相应操作即完成了Ajax通信过程。ExtJS以及jQuery等库都对Ajax过程进行了不同程度的封装,以简化异步请求过程。

ExtJS的Ajax使用方法简介

ExtJS的封装比较完全,目前ExtJS进行异步通信的常规手段都是采用Model+Store的方式,对组件内容进行动态更新,已经比较少使用Ext.Ajax的方法了。但前一种方式只是对Ext.Ajax方法的进一步封装,其实现原理类似,故此处仍然先对Ext.Ajax进行说明。

1
2
3
4
5
6
7
8
9
10
11
12
//以下是主要的属性和方法,此外还有failure等
Ext.Ajax.request({
url: 'page.php', //设置url,可以带请求参数
method: "get", //设置请求方法
params: { //设置要发送的参数,可发送多个参数
id: 1
},
success: function(response){ //请求的数据返回成功则执行

var text = response.responseText;
// process server response here
}
});

ExtJS的Ext.Ajax.request底层实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
request : function(options) {

//初始化
options = options || {};
var me = this,
scope = options.scope || window,
username = options.username || me.username,
password = options.password || me.password || '',
async,
requestOptions,
request,
headers,
xhr;
if (me.fireEvent('beforerequest', me, options) !== false) {

requestOptions = me.setOptions(options, scope);

if (me.isFormUpload(options)) {
me.upload(options.form, requestOptions.url, requestOptions.data, options);
return null;
}

// 如果设置了自动取消异步,则调用abort()方法,取消异步请求
if (options.autoAbort || me.autoAbort) {
me.abort();
}

async = options.async !== false ? (options.async || me.async) : false;
// 创建一个XHR对象实例,此处多了用户名和密码两个参数
// 函数进行性能检测,ie返回的是xdr实例,存在xhr返回xhr实例
xhr = me.openRequest(options, requestOptions, async, username, password);

// 如果不是XDR,则设置相应头部
if (!me.isXdr) {
headers = me.setupHeaders(xhr, options, requestOptions.data, requestOptions.params);
}

// 创建请求实例
request = {
id: ++Ext.data.Connection.requestId, //自动设置id以进行区分
xhr: xhr,
headers: headers,
options: options,
async: async,
binary: options.binary || me.binary,
timeout: setTimeout(function() {
request.timedout = true;
me.abort(request);
}, options.timeout || me.timeout)
};

me.requests[request.id] = request;
me.latestId = request.id;

// 绑定statechange事件函数,状态发生改变则发生相应事件
if (async) {
if (!me.isXdr) {
xhr.onreadystatechange = Ext.Function.bind(me.onStateChange, me, [request]);
}
}

//如果是XDR,则使用一下方法绑定request
if (me.isXdr) {
me.processXdrRequest(request, xhr);
}

// 开始进行请求
xhr.send(requestOptions.data);
if (!async) {
return me.onComplete(request);
}
return request;
} else {
Ext.callback(options.callback, options.scope, [options, undefined, undefined]);
return null;
}
},

ExtJS中load()与reload()

ExtJS可以通过store的load()和reload()方法隐式实现Ajax请求及响应,为对Ajax的应用级别的封装。下面为load()、reload()流程:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
//reload方法,为更改最新属性,再次使用load()方法
reload: function(options) {
var o = Ext.apply({}, options, this.lastOptions);
return this.load(o);
},


load: function(options) {
var me = this,
operation = {
action: 'read'
};

// ……

if (me.fireEvent('beforeload', me, operation) !== false) {
me.loading = true;
//调用read方法
me.proxy.read(operation, me.onProxyLoad, me);
}

return me;
},

//调用Ajax请求
read: function() {
return this.doRequest.apply(this, arguments);
},

doRequest: function(operation, callback, scope) {

//……

Ext.Ajax.request(request);

return request;
},