ExtJs----數(shù)據(jù)存儲與傳輸
Ext.data.Connection
Ext.data.Connection是對Ext.lib.Ajax的封裝,它提供了配置使用Ajax的通用方式,它在內(nèi)部通過Ext.lib.Ajax實現(xiàn)與后臺的異步調(diào)用。與底層的Ext.lib.Ajax相比,Ext.data.Connection提供了更簡潔的配置方式,使用起來更方便。
Ext.data.Connection主要用于在Ext.data.HttpProxy和Ext.data.ScriptTagProxy中執(zhí)行與后臺交互的任務(wù),它會從指定的URL獲取數(shù)據(jù),并把后臺返回的數(shù)據(jù)交給HttpProxy或ScriptTagPrxoy處理。
url:String: 請求url。
params:Object/String/Function: 請求傳遞的參數(shù)。
methos:String:請求方法,通常為GET或POST
callback:Function:請求完成后的回調(diào)函數(shù),無論是否成功還是失敗,都會執(zhí)行。
success:Function:請求成功時的回調(diào)函數(shù)。
failure:Function:請求失敗時的回調(diào)函數(shù)。
scope:Object:回調(diào)函數(shù)的作用域。
form:Object:綁定的form表單。
isUpload:Boolean:是否執(zhí)行文件上傳。
headers:Object:請求首部信息
xmlData:Object:XML文檔對象,可以通過URL附加參數(shù)的方式發(fā)起請求。
disableCaching:Boolean:是否禁用緩存,默認(rèn)為禁用。
Ext.data.Connection還提供了abort([Number transactionId]函數(shù)),當(dāng)同時有多個請求發(fā)生時,根據(jù)指定的事務(wù)id放棄其中的某一個請求。如果不指定事務(wù)id,就會放棄最后一個請求。isLoading(Number transactionId)函數(shù)的用法與abort()類似,可以根據(jù)事務(wù)id判斷對應(yīng)的請求是否完成。如果未指定事務(wù)id,就判斷最后一個請求是否完成。
Ext.data.Record
Ext.data.Record就是一個設(shè)定了內(nèi)部數(shù)據(jù)類型的對象,它是Ext.data.Store的最基本組成部分。如果Ext.data.Store看作是二維表,那么它的每一行就對應(yīng)一個Ext.data.Record實例。
實例中,15--17行都對屬性賦值,但建議使用set()方法。因為set()函數(shù)會判斷屬性值是否發(fā)生了變化,如果改變了,就要將當(dāng)前對象的dirty屬性設(shè)置為true,并將修改之前的原始值放入modified對象中,供其他函數(shù)調(diào)用。
Record的屬性數(shù)據(jù)被修改后,可以執(zhí)行如下幾種操作:
commit():這個函數(shù)的效果是設(shè)置dirty為false,并刪除modified中保存的原始數(shù)據(jù)。
reject():這個函數(shù)的效果是將data中已經(jīng)修改的屬性值恢復(fù)為modified的原始數(shù)據(jù),然后設(shè)置dirty為false,并刪除保存在原始數(shù)據(jù)的modified對象。
getChanges():這個函數(shù)會把data中經(jīng)過修改的屬性和數(shù)據(jù)放在一個JSON對象并返回。
我們還可以調(diào)用isModified()判斷當(dāng)前record中的數(shù)據(jù)是否被修改。還可以使用copy()函數(shù)復(fù)制record實例。
Ext.data.Store
Ext.data.Store中有一個Ext.data.Record數(shù)組,所有數(shù)據(jù)都存放在這些Ext.data.Record實例中。
//Ext.data.Store的基本用法
var data = [
['boy',0],
['girl',1]
];

var store = new Ext.data.Store({
proxy:new Ext.data.MemoryProxy(data),
render:new Ext.data.ArrayReader({}, PersonRecord)
});
store.load();
每個store最少需要兩個組件的支持,分別是proxy和reader,proxy用于從某個途徑讀取原始數(shù)據(jù),reader用于將原始數(shù)據(jù)轉(zhuǎn)換成Record實例。實例中使用Ext.data.MemoryProxy和Ext.data.ArrayReader,將data數(shù)組中的數(shù)據(jù)轉(zhuǎn)換成對應(yīng)的幾個PersonRecord實例,然后放入store中。store創(chuàng)建完畢后,執(zhí)行store.load()實現(xiàn)這個轉(zhuǎn)換過程。
//對name字段進(jìn)行降序排列
var store = new Ext.data.Store({
proxy:new Ext.data.MemoryProxy(data),
reader:new Ext.data.ArrayReader({},PersonRecord),
sortInfo:{field:'name',direction:'DESC'}
});
修改record的內(nèi)部數(shù)據(jù)之后有兩種選擇:執(zhí)行rejectChanges()撤銷所有修改,將修改過的record恢復(fù)到原來的狀態(tài);執(zhí)行commitChanges()提交數(shù)據(jù)修改。在執(zhí)行撤銷和提交操作之前,可以使用getModifiedRecords()獲得store中修改過的record數(shù)組。與修改數(shù)據(jù)相關(guān)的參數(shù)是pruneModifiedRecoreds,如果將它設(shè)置為true,當(dāng)每次執(zhí)行刪除或reload操作時,都會清空所有修改。這樣,在每次執(zhí)行刪除或reload操作之后,getModifiedRecords()返回的就是一個空數(shù)組,否則仍然會得到上次修改過的record記錄。
為store加載數(shù)據(jù)之后,有時不需要把所有的數(shù)據(jù)都顯示出來,這是可以使用函數(shù)filter和filterBy對store中的數(shù)據(jù)進(jìn)行過濾,只顯示符合條件的部分;如果想取消過濾,則使用clearFilter()函數(shù)。
store還有其他一些有用的函數(shù):
collect(String dataIndex, [Boolean allowNull], [Boolean bypassFilter]):Array 獲得指定的dataIndex對應(yīng)的那一列的數(shù)據(jù)。當(dāng)allowNull參數(shù)為true時,返回的結(jié)果中可能會包含null, undefined或空字符串,否則collect函數(shù)會自動將這些空數(shù)據(jù)過濾掉。當(dāng)bypassFilter參數(shù)為true時,collect的結(jié)果不會受查詢條件的影響,無論查詢條件是什么都會忽略掉,返回的信息是所有的數(shù)據(jù)
getTotalCount():用于翻頁時獲得后臺傳遞過來的數(shù)據(jù)總數(shù)。如果沒有設(shè)置翻頁,getTotalCount()結(jié)果與getCount()相同,都是返回當(dāng)前的數(shù)據(jù)總數(shù)。
indexOf(Ext.data.Record record)和indexOfId(String id)函數(shù)根據(jù)record或record的id獲得record對應(yīng)的行號。
loadData(object data,[Boolean append])從本地JavaScript變量中讀取數(shù)據(jù),append為true時,將讀取的數(shù)據(jù)附加到原數(shù)據(jù)后,否則執(zhí)行整體更新。
Sum(String property, Number start, Number end):用于計算某一列從start到end的總數(shù)
MemoryProxy
MemoryProxy只能從JavaScript對象獲得數(shù)據(jù),可以直接把數(shù)組,或JSON和XML格式的數(shù)據(jù)交給它處理。
HttpProxy
HttpProxy使用Http協(xié)議,通過Ajax去后臺取數(shù)據(jù),構(gòu)造它時需要設(shè)置url:'xxx.jsp'參數(shù)。需要注意的是,HttpProxy不支持跨域,只能從同一域中獲取數(shù)據(jù)。如果想跨域,參考ScriptTagProxy。
ScriptTagPrxoy
ScriptTagProxy的用法幾乎和HttpProxy一樣,var proxy = new Ext.data.ScriptTagProxy({url:'xxx.jsp'});
前臺看不出它是如何支持跨域的,我們還需要在后臺進(jìn)行相應(yīng)的處理,如:
Ext.data.Connection是對Ext.lib.Ajax的封裝,它提供了配置使用Ajax的通用方式,它在內(nèi)部通過Ext.lib.Ajax實現(xiàn)與后臺的異步調(diào)用。與底層的Ext.lib.Ajax相比,Ext.data.Connection提供了更簡潔的配置方式,使用起來更方便。
Ext.data.Connection主要用于在Ext.data.HttpProxy和Ext.data.ScriptTagProxy中執(zhí)行與后臺交互的任務(wù),它會從指定的URL獲取數(shù)據(jù),并把后臺返回的數(shù)據(jù)交給HttpProxy或ScriptTagPrxoy處理。
1
var conn = new Ext.data.Connection({
2
autoAbort:false,
3
defaultHeaders:{
4
referer:'http://localhost:8080'
5
},
6
disableCaching:false,
7
extraParams:{
8
name:'name'
9
},
10
method:'GET',
11
timeout:300,
12
url:'01-01.txt'
13
});
14
15
conn.request({
16
success:function(response){
17
Ext.Msg.alert('info',response.responseText);
18
},
19
failure:function(){
20
Ext.Msg.alert('warn','failure');
21
}
22
});

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

url:String: 請求url。
params:Object/String/Function: 請求傳遞的參數(shù)。
methos:String:請求方法,通常為GET或POST
callback:Function:請求完成后的回調(diào)函數(shù),無論是否成功還是失敗,都會執(zhí)行。
success:Function:請求成功時的回調(diào)函數(shù)。
failure:Function:請求失敗時的回調(diào)函數(shù)。
scope:Object:回調(diào)函數(shù)的作用域。
form:Object:綁定的form表單。
isUpload:Boolean:是否執(zhí)行文件上傳。
headers:Object:請求首部信息
xmlData:Object:XML文檔對象,可以通過URL附加參數(shù)的方式發(fā)起請求。
disableCaching:Boolean:是否禁用緩存,默認(rèn)為禁用。
Ext.data.Connection還提供了abort([Number transactionId]函數(shù)),當(dāng)同時有多個請求發(fā)生時,根據(jù)指定的事務(wù)id放棄其中的某一個請求。如果不指定事務(wù)id,就會放棄最后一個請求。isLoading(Number transactionId)函數(shù)的用法與abort()類似,可以根據(jù)事務(wù)id判斷對應(yīng)的請求是否完成。如果未指定事務(wù)id,就判斷最后一個請求是否完成。
Ext.data.Record
Ext.data.Record就是一個設(shè)定了內(nèi)部數(shù)據(jù)類型的對象,它是Ext.data.Store的最基本組成部分。如果Ext.data.Store看作是二維表,那么它的每一行就對應(yīng)一個Ext.data.Record實例。
1
var PersonRecord = Ext.data.Record.create({
2
{name:'name',type:'string'},
3
{name:'sex',type:'int'}
4
});
5
6
var boy = new PersonRecord({
7
name:'boy',
8
sex:0
9
});
10
11
alert(boy.data.name);
12
alert(boy.data['name']);
13
alert(boy.get('name'));
14
15
boy.data.name = 'boy name';
16
boy.data['name'] = 'boy name';
17
boy.set('name','boy name');

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

實例中,15--17行都對屬性賦值,但建議使用set()方法。因為set()函數(shù)會判斷屬性值是否發(fā)生了變化,如果改變了,就要將當(dāng)前對象的dirty屬性設(shè)置為true,并將修改之前的原始值放入modified對象中,供其他函數(shù)調(diào)用。
Record的屬性數(shù)據(jù)被修改后,可以執(zhí)行如下幾種操作:
commit():這個函數(shù)的效果是設(shè)置dirty為false,并刪除modified中保存的原始數(shù)據(jù)。
reject():這個函數(shù)的效果是將data中已經(jīng)修改的屬性值恢復(fù)為modified的原始數(shù)據(jù),然后設(shè)置dirty為false,并刪除保存在原始數(shù)據(jù)的modified對象。
getChanges():這個函數(shù)會把data中經(jīng)過修改的屬性和數(shù)據(jù)放在一個JSON對象并返回。
我們還可以調(diào)用isModified()判斷當(dāng)前record中的數(shù)據(jù)是否被修改。還可以使用copy()函數(shù)復(fù)制record實例。
Ext.data.Store
Ext.data.Store中有一個Ext.data.Record數(shù)組,所有數(shù)據(jù)都存放在這些Ext.data.Record實例中。

















1
//更新store中的數(shù)據(jù)
2
store.add(new PersonRecord({
3
name:'other',
4
sex:0
5
}));
6
7
//add()也可以添加一個record數(shù)組
8
store.add([new PersonRecord({
9
name:'other1',
10
sex:0
11
}),new PersonRecord({
12
name:'other2',
13
sex:1
14
})]);
15
16
//add()方法會將數(shù)據(jù)添加入最后一條數(shù)據(jù),這樣破壞了原本的排序方式
17
//addSorted()可以保證數(shù)據(jù)有序
18
store.addSorted(new PersonRecord({
19
name:'other',
20
sex:0
21
}));
22
23
//使用insert()指定插入位置
24
store.insert(3,new PersonRecord({
25
name:'other',
26
sex:0
27
}));
28
29
//刪除操作
30
store.remove(store.getAt(0));
31
store.removeAll();
32
33
//修改數(shù)據(jù)
34
store.getAt(0).set('name','xxx');
35
36

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

修改record的內(nèi)部數(shù)據(jù)之后有兩種選擇:執(zhí)行rejectChanges()撤銷所有修改,將修改過的record恢復(fù)到原來的狀態(tài);執(zhí)行commitChanges()提交數(shù)據(jù)修改。在執(zhí)行撤銷和提交操作之前,可以使用getModifiedRecords()獲得store中修改過的record數(shù)組。與修改數(shù)據(jù)相關(guān)的參數(shù)是pruneModifiedRecoreds,如果將它設(shè)置為true,當(dāng)每次執(zhí)行刪除或reload操作時,都會清空所有修改。這樣,在每次執(zhí)行刪除或reload操作之后,getModifiedRecords()返回的就是一個空數(shù)組,否則仍然會得到上次修改過的record記錄。
1
store.load({
2
params:{start:0,limit:20} //參數(shù)
3
callback:function(records,options,success){
4
Ext.Msg.alert('info','加載完畢'); //回調(diào)函數(shù)
5
}
6
scope:store,
7
add:true
8
});
callback是加載完畢時執(zhí)行的回調(diào)函數(shù),records參數(shù)表示獲得的數(shù)據(jù);options表示執(zhí)行l(wèi)oad()時傳遞的參數(shù),success表示加載是否成功。
2

3

4

5

6

7

8

為store加載數(shù)據(jù)之后,有時不需要把所有的數(shù)據(jù)都顯示出來,這是可以使用函數(shù)filter和filterBy對store中的數(shù)據(jù)進(jìn)行過濾,只顯示符合條件的部分;如果想取消過濾,則使用clearFilter()函數(shù)。
store還有其他一些有用的函數(shù):
collect(String dataIndex, [Boolean allowNull], [Boolean bypassFilter]):Array 獲得指定的dataIndex對應(yīng)的那一列的數(shù)據(jù)。當(dāng)allowNull參數(shù)為true時,返回的結(jié)果中可能會包含null, undefined或空字符串,否則collect函數(shù)會自動將這些空數(shù)據(jù)過濾掉。當(dāng)bypassFilter參數(shù)為true時,collect的結(jié)果不會受查詢條件的影響,無論查詢條件是什么都會忽略掉,返回的信息是所有的數(shù)據(jù)
getTotalCount():用于翻頁時獲得后臺傳遞過來的數(shù)據(jù)總數(shù)。如果沒有設(shè)置翻頁,getTotalCount()結(jié)果與getCount()相同,都是返回當(dāng)前的數(shù)據(jù)總數(shù)。
indexOf(Ext.data.Record record)和indexOfId(String id)函數(shù)根據(jù)record或record的id獲得record對應(yīng)的行號。
loadData(object data,[Boolean append])從本地JavaScript變量中讀取數(shù)據(jù),append為true時,將讀取的數(shù)據(jù)附加到原數(shù)據(jù)后,否則執(zhí)行整體更新。
Sum(String property, Number start, Number end):用于計算某一列從start到end的總數(shù)
MemoryProxy
MemoryProxy只能從JavaScript對象獲得數(shù)據(jù),可以直接把數(shù)組,或JSON和XML格式的數(shù)據(jù)交給它處理。
HttpProxy
HttpProxy使用Http協(xié)議,通過Ajax去后臺取數(shù)據(jù),構(gòu)造它時需要設(shè)置url:'xxx.jsp'參數(shù)。需要注意的是,HttpProxy不支持跨域,只能從同一域中獲取數(shù)據(jù)。如果想跨域,參考ScriptTagProxy。
ScriptTagPrxoy
ScriptTagProxy的用法幾乎和HttpProxy一樣,var proxy = new Ext.data.ScriptTagProxy({url:'xxx.jsp'});
前臺看不出它是如何支持跨域的,我們還需要在后臺進(jìn)行相應(yīng)的處理,如:
1
String cb = request.getParameter("callback");
2
response.setContentType("text/javascript");
3
Writer out = response.getWriter();
4
out.write(cb + "(");
5
out.print("[" +
6
"['id1','name1','descn1']" +
7
"['id2','name2','descn2']" +
8
"]");
9
out.wirte(");");
其中的關(guān)鍵就在于從請求中獲得的callback參數(shù),這個參數(shù)叫做回調(diào)函數(shù)。ScriptTagProxy會在當(dāng)前的HTML頁面添加一個<script type="text/javascript" scr="xxx.jsp"></script>標(biāo)簽,然后把后臺返回的內(nèi)容添加到這個標(biāo)簽中,這樣就可以解決跨域訪問數(shù)據(jù)的問題。為了讓后臺返回的內(nèi)容可以再動態(tài)生成的標(biāo)簽中運行,EXT會生成一個名為callback的回調(diào)函數(shù),并把回調(diào)函數(shù)的名稱傳遞給后臺,由后臺生成callback(data)形式的響應(yīng)內(nèi)容,然后返回給前臺自動運行。 
2

3

4

5

6

7

8

9
