随着现在各种js 框架(例如extjs,Jquery)的迅猛发展,很多网站都开始使用这些框架开始设计
web 页面,而且为了提高用户体验,大量使用了AJAX 技术,可以动态实现很多网页内容,
本文就以extjs 的grid 为例,介绍一下使用webbroke的服务器 与js 框架的交互。
先看一下下面的页面:
这个页面动态显示一个人员工资表,并可以实现翻页,这是一个典型的extjs 的grid。
其页面代码如下:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=gb3212">
<title>你好</title>
<link rel="stylesheet" type="text/css" href="/extjs/resources/css/ext-all.css" />
<script type="text/javascript" src="/extjs/adapter/ext/ext-base.js"></script>
<script type="text/javascript" src="/extjs/ext-all.js"></script>
<script type="text/javascript" >
Ext.onReady(function(){
Ext.BLANK_IMAGE_URL="/extjs/resources/images/default/s.gif";
// create the Data Store
var store = new Ext.data.JsonStore({
root: 'topics',
totalProperty: 'totalCount',
idProperty: 'threadid',
remoteSort: true,
fields: [
'XH', 'XM', 'PYM', 'RSXH',
{name: 'BYTS', type: 'int'},
'JBGZ',
{name:'HJ',type:'float'}, 'SFZH'
],
proxy: new Ext.data.HttpProxy({
url: '/web/oa?path=getdata'
})
});
store.setDefaultSort('BH', 'desc');
// pluggable renders
function renderTopic(value, p, record){
return String.format(
'<b><a href="http://extjs.com/forum/showthread.php?t={2}" target="_blank">{0}</a></b><a href="http://extjs.com/forum/forumdisplay.php?f={3}" target="_blank">{1} Forum</a>',
value, record.data.forumtitle, record.id, record.data.forumid);
}
function renderLast(value, p, r){
return String.format('{0}<br/>by {1}', value.dateFormat('M j, Y, g:i a'), r.data['lastposter']);
}
var pagingBar = new Ext.PagingToolbar({
pageSize: 25,
store: store,
displayInfo: true,
displayMsg: '显示人数 {0} - {1} of {2}',
emptyMsg: "没有数据",
items:[
'-', {
pressed: true,
enableToggle:true,
text: '显示预览',
cls: 'x-btn-text-icon details',
toggleHandler: function(btn, pressed){
var view = grid.getView();
view.showPreview = pressed;
view.refresh();
}
}]
});
var grid = new Ext.grid.GridPanel({
el:'topic-grid',
width:700,
height:500,
title:'人员工资表',
store: store,
trackMouseOver:false,
disableSelection:true,
loadMask: true,
// grid columns
columns:[{
id: 'topic', // id assigned so we can apply custom css (e.g. .x-grid-col-topic b { color:#333 })
header: "编号",
dataIndex: 'XH',
width: 420,
// renderer: renderTopic,
sortable: true
},{
header: "姓名",
dataIndex: 'XM',
width: 100,
align: 'right',
//hidden: true,
sortable: true
},{
header: "拼音码",
dataIndex: 'PYM',
width: 70,
align: 'right',
sortable: true
},{
header: "本月天数",
dataIndex: 'BYTS',
width: 70,
align: 'right',
sortable: true
},{
id: 'lastpost',
header: "实发工资",
dataIndex: 'HJ',
width: 150,
// renderer: renderLast,
sortable: true
}],
// customize view config
viewConfig: {
forceFit:true,
enableRowBody:true,
showPreview:true,
getRowClass : function(record, rowIndex, p, store){
if(this.showPreview){
p.body = '<p>人事序号 :'+record.data.RSXH+'</p>';
return 'x-grid3-row-expanded';
}
return 'x-grid3-row-collapsed';
}
},
// paging bar on the bottom
bbar: pagingBar
});
// render it
grid.render();
// trigger the data store load
store.load({params:{start:0, limit:25}});
});
/**
* @class Ext.ux.SliderTip
* @extends Ext.Tip
* Simple plugin for using an Ext.Tip with a slider to show the slider value
*/
Ext.ux.SliderTip = Ext.extend(Ext.Tip, {
minWidth: 10,
offsets : [0, -10],
init : function(slider){
slider.on('dragstart', this.onSlide, this);
slider.on('drag', this.onSlide, this);
slider.on('dragend', this.hide, this);
slider.on('destroy', this.destroy, this);
},
onSlide : function(slider){
this.show();
this.body.update(this.getText(slider));
this.doAutoWidth();
this.el.alignTo(slider.thumb, 'b-t?', this.offsets);
},
getText : function(slider){
return slider.getValue();
}
});
</script>
<link rel="stylesheet" type="text/css" href="/ib/grid-examples.css" />
<!-- Common Styles for the examples -->
<link rel="stylesheet" type="text/css" href="/ib/examples.css" />
</head>
<body>
<script type="text/javascript" src="../shared/examples.js"></script><!-- EXAMPLES -->
<div id="topic-grid"></div>
</body>
</html>
这个页面主要是使用这一句来获取服务器端的数据
proxy: new Ext.data.HttpProxy({
url: '/web/oa?path=getdata'
})
而extjs 需要的是json 数据,而URL:/web/oa?path=getdata 就是要返回对应的json 串。
getdata 的脚本代码为:
<%
uses SysUtils, Classes;
var
start,limit,sort,dir:string;
s:string;
begin
start:=request.queryfields.values['start'];
limit:=request.queryfields.values['limit'];
sort:=request.queryfields.values['sort'];
dir:=request.queryfields.values['dir'];
s:='select * from gjj ';
if sort<>'' then
s:=s+' order by "'+sort+'"'+ ' '+dir;
print(wm.datatojson( s,'0','',nil));
end.
%>
函数datatojson 的作用就是根据sql 和开始行及每页显示数及参数 生成数据集,并根据数据集生成
extjs 需要的JSON 串。为了生成JSON 我们使用了开源的Super Object Toolkit(呵呵,这个是免费的),
然后在服务器端实现这个函数就可以了(本例以oracle数据库为参考)。
function Twm.datatojson(datasql, startp, endp: string;
inparams: tstringlist = nil): string;
var
alljson: ISuperObject;
datajson: ISuperObject;
recordjson: ISuperObject;
mycx: Twebquery;
totalcount: string;
starti, endi, i: integer;
begin
if startp = '' then
starti := 0
else
starti := strtoint(startp);
alljson := TSuperObject.Create(stobject);
mycx := Twebquery.Create(self);
mycx.Connection := dbs ;
mycx.sql.clear;
mycx.sql.add('select count(*) from (' + datasql + ')');
if inparams <> nil then
begin
for i := 0 to inparams.Count - 1 do
begin
if inparams.Names[i] <> '' then
begin
mycx.Parambyname(inparams.Names[i]).AsString :=
inparams.ValueFromIndex[i];
end;
end;
end;
try
mycx.Open;
except
on E:Exception do
begin
result:='数据库打开错误!'+e.Message;
exit;
end;
end;
totalcount := mycx.fields[0].AsString;
if totalcount > '0' then
begin
datajson := TSuperObject.Create(starray);
with mycx do
begin
sql.clear;
if endp = '' then
endi := StrToInt(totalcount)
else
endi := strtoint(endp);
sql.Add(' select * from ( select tttz.*,rownum as nnnz from (');
sql.add(datasql);
sql.Add(') tttz )');
sql.Add(' where nnnz>='+IntToStr(starti + 1) +' and nnnz<='+IntToStr(starti + endi));
if inparams <> nil then
begin
for i := 0 to inparams.Count - 1 do
begin
if inparams.Names[i] <> '' then
begin
mycx.Parambyname(inparams.Names[i]).AsString :=
inparams.ValueFromIndex[i];
end;
end;
end;
try
Open;
except
result:='数据库打开错误!2';
exit;
end;
while not eof do
begin
recordjson := TSuperObject.Create(stobject);
for i := 0 to fields.Count - 1 do
begin
recordjson.s[fields[i].FieldName] := fields[i].AsString;
end;
datajson.o[''] := recordjson;
recordjson := nil;
next;
end;
end;
alljson.o['topics'] := datajson;
alljson.s['totalCount'] := totalcount;
datajson := nil;
end;
result := alljson.AsJSon();
mycx.Free;
alljson := nil;
end;
这样我们的服务器就可以与extjs 交互,并产生上面的页面了。
呵呵,是不是很酷,很简单?