在ExtJS的下拉元件(ComboBox)中,如果資料量過多的話,可能會在第一次點擊時因為要
組成相關的DOM而導致瀏覽器執行指令碼過久的情形,可能會造成無回應的情況(如IE)。
因此在這邊簡單說明如何使用分頁功能,如此一來當點擊下拉時只需建立當下的分頁內容
,避免一次從後端傳回所有的資料。
前端程式
跟建立Grid一樣,您需要定義store、record,store為跟後端要求資料的儲存體,同時會定義
回傳的格式,並搭配record來取得mapping的資料。
在這邊的record共定義了兩個欄位,分別為下拉選單的value(code_no)及text(code_na)
屬性root,表示JSON格式的key為rows,對應得值即為[{"code_no":"1", "code_na":"YES"},
{"code_no":"2", "code_na":"NO"}]
屬性totalProperty,表示JSON格式的key為totalRows,對應的為一總資料量的數值,如此才
可以提供元件算出頁數
接下來為定義ComboBox本身
需注意的為設定屬性pageSize,在此設定為5表示一頁顯示五筆資料。而valueField、
displayField分別為code_no、code_na。
後端程式
在這邊要注意的是從前端固定會傳送參數start、limit,如您第一次點下拉,會傳送start => 0
、limit => 5的值到後端。此時您就可以依據查詢出來的資料集(ResultSet),來進一步組rows
key要對應的資料(應該為前5筆),totalRows要塞的是整體的數量。所以,當您點擊下一頁時
,start => 5、limit => 5,以此類推。在這邊的寫法會在每一次進入composeComboBoxData時
重新作查詢,您可以修改成第一次查詢時存進一List內,到時在下一次進入時直接針對該List
取得需要的資料區間即可,這樣就不用每一次查詢資料庫了。最後進行response輸出。
組成相關的DOM而導致瀏覽器執行指令碼過久的情形,可能會造成無回應的情況(如IE)。
因此在這邊簡單說明如何使用分頁功能,如此一來當點擊下拉時只需建立當下的分頁內容
,避免一次從後端傳回所有的資料。
前端程式
跟建立Grid一樣,您需要定義store、record,store為跟後端要求資料的儲存體,同時會定義
回傳的格式,並搭配record來取得mapping的資料。
var signnoColumns = Ext.data.Record.create([{name: "code_no", type:'String'},{name: "code_na", type:'String'}]);
var signnoStore = new Ext.data.Store({
// load using HTTP
url: "<%=request.getContextPath()%>/ActionServlet?action=composeComboBoxData",
// 此讀取器可以解析JSON DATA, 並轉換成Record. Record需定義其欄位名稱與型別
reader: new Ext.data.JsonReader({
root: 'rows',
totalProperty: 'totalRows',
fields: signnoColumns
})
});
在這邊的record共定義了兩個欄位,分別為下拉選單的value(code_no)及text(code_na)
屬性root,表示JSON格式的key為rows,對應得值即為[{"code_no":"1", "code_na":"YES"},
{"code_no":"2", "code_na":"NO"}]
屬性totalProperty,表示JSON格式的key為totalRows,對應的為一總資料量的數值,如此才
可以提供元件算出頁數
接下來為定義ComboBox本身
var signnoCombo = new Ext.form.ComboBox({
valueField: 'code_no',
displayName: '員工編號',
allowBlank: true,
typeAhead: false,
triggerAction: 'all',
transform:'signno',
forceSelection:false,
resizable:true,
width:100,
listWidth:250,
minChars:0,
lazyRender:false,
store: signnoStore,
displayField: 'code_na',
selectOnFocus:false,
pageSize:5
});
<input type="text" name="signno" id="signno" value="" size="10">
需注意的為設定屬性pageSize,在此設定為5表示一頁顯示五筆資料。而valueField、
displayField分別為code_no、code_na。
後端程式
public void composeComboBoxData(HttpServletRequest request){
System.out.println("action composeComboBoxData");
DatabaseDAO dao = new DatabaseDAO();
JSONObject jsonData = new JSONObject();
JSONArray rowArray = new JSONArray();
int start = Integer.parseInt(request.getParameter("start"));
int limit = Integer.parseInt(request.getParameter("limit"));
System.out.println(start+"--"+limit);
int index = 0;
try {
Map<String, String> rowdata = new HashMap<>();
ResultSet rs = dao.getResultSet("select distinct signno code_no, signno code_na from paydetail");
while(rs.next()){
if(index >= start && start+limit > index){
rowdata.put("code_no", rs.getString("code_no"));
rowdata.put("code_na", rs.getString("code_na"));
rowArray.put(new JSONObject(rowdata));
}
index++;
}
jsonData.put("rows", rowArray);
jsonData.put("totalRows", index);
outputResponse(jsonData.toString());
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally{
try {
dao.releaseConnection();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
在這邊要注意的是從前端固定會傳送參數start、limit,如您第一次點下拉,會傳送start => 0
、limit => 5的值到後端。此時您就可以依據查詢出來的資料集(ResultSet),來進一步組rows
key要對應的資料(應該為前5筆),totalRows要塞的是整體的數量。所以,當您點擊下一頁時
,start => 5、limit => 5,以此類推。在這邊的寫法會在每一次進入composeComboBoxData時
重新作查詢,您可以修改成第一次查詢時存進一List內,到時在下一次進入時直接針對該List
取得需要的資料區間即可,這樣就不用每一次查詢資料庫了。最後進行response輸出。
留言
張貼留言