使用ExtJS GridPanel从Web Service 获取、绑定和显示数据
本文将向大家介绍一种使用 ExtJS 的 GridPanel 组件从 ASP.NET Web Service 获取 XML 数据并进行绑定和显示的方法。
GridPanel 组件在进行数据绑定时可以接收多种数据格式。其中以 JSON 和 XML 最为常见。如果要给 GridPanel 绑定 JSON 格式的数据(这也是网上“通用”和“热门”的解决方案),那么我们需要修改 Web Service 的 Web.config 设置,将输出数据的格式改为 JSON(默认为 XML。设置方法可参见:http://www.cnblogs.com/regedit/archive/2008/03/04/1089948.html 一文)。
个人认为此方法过于繁琐,为了保证对现有的 Web Service 不做较大的调整,我决定还是继续让其返回 XML 格式的数据。因此在对 GridPanel 进行数据绑定时就要选用 XML 方式绑定了。也就是说,我们在绑定数据时要使用 Ext.data.XmlReader 而不是 Ext.data.JsonReader。具体的实现方法如下:
1. Web Service 部分:
usingSystem.Web;
usingSystem.Collections;
usingSystem.Web.Services;
usingSystem.Web.Services.Protocols;
usingSystem.Configuration;
usingSystem.Data;
usingSystem.Data.SqlClient;
[WebService(Namespace="http://tempuri.org/")]
[WebServiceBinding(ConformsTo=WsiProfiles.BasicProfile1_1)]
publicclassArticleService:System.Web.Services.WebService{
//SQL连接字符串
privatereadonlystring_strConn=ConfigurationManager.ConnectionStrings["Junchieh"].ConnectionString;
//从start开始limit行,按sort字段排序,排序方式为dir(将传入"asc"或"desc")
[WebMethod]
publicDataSetGetArticles(intstart,intlimit,stringsort,stringdir)
{
DataSetds=newDataSet("Article");
//从数据库获取数据,放入record表
stringstrSql=string.Format(
"selecttop{0}*fromArticlewhereIdnotin(selecttop{1}IdfromArticleorderby{2}{3})orderby{2}{3}",
limit,start,sort,dir);
SqlDataAdapterda=newSqlDataAdapter(strSql,_strConn);
DataTabledtRecord=newDataTable("record");
lock(da)
{
da.Fill(dtRecord);
}
ds.Tables.Add(dtRecord);
//计算总行数,放入results表
DataTabledtResult=newDataTable("results");
dtResult.Columns.Add("totalRecords");
DataRowdr=dtResult.NewRow();
using(SqlConnectionconn=newSqlConnection(_strConn))
using(SqlCommandcmd=newSqlCommand("selectcount(*)fromArticle",conn))
{
try
{
conn.Open();
dr["totalRecords"]=(int)cmd.ExecuteScalar();
}
catch
{
//donothing
}
}
dtResult.Rows.Add(dr);
ds.Tables.Add(dtResult);
returnds;
}
}
GetAritcles 将返回一个 DataSet。其内包括两个 DataTable,第一个存放了(跟据 start 和 limit 参数指定的)当前页的数据,另一个存放了数据库中所有数据的行数,供客户端的 GridPanel 组件使用。 客户端部分(节选):
Ext.onReady(function(){
//列
varcm=newExt.grid.ColumnModel([
{header:'ID',dataIndex:'Id',sortable:true,width:10},
{header:'标题',dataIndex:'Title',sortable:true},
{header:'日期',dataIndex:'Date',sortable:true,width:50,renderer:renderDate} // 在renderDate函数中格式化
]);
//数据源
varstore=newExt.data.Store({
url:'Services/ArticleService.asmx/GetArticles',//WebService地址
reader:newExt.data.XmlReader(
{
totalRecords:'totalRecords',//数据总行数。对应于GetArticles返回的DataSet中的 results表的totalRecores列
record:'record', //数据。对应于GetArticles返回的DataSet中的 record表
id:'Id'//主键。对应于GetArticles返回的DataSet中的 record表的Id列
},
[
{name:'Id'},
{name:'Title'},
{name:'Date'}
]
),
remoteSort:true// 服务端排序
});
store.setDefaultSort('Date','desc'); //默认按Date列降序排列
// 分页栏
varbbar=newExt.PagingToolbar(
{
pageSize:4,
store:store,
displayInfo:true,
displayMsg:'当前显示{0}-{1}条,共{2}条',
emptyMsg:"无数据"
}
);
//GridPanel 组件
vargrid=newExt.grid.GridPanel({
frame:true,
enableHdMenu:false,
width:600,
height:300,
title:'文章列表',
loadMask:{msg:'正在加载数据,请稍侯……'},
el:'grid',
store:store,
cm:cm,
bbar:bbar,
viewConfig:{
forceFit:true
}
});
grid.render();
store.load({params:{start:0,limit:4}});//初始时显示第1页,每页显示4条数据
});
//格式化日期
//将XML数据中的原始日期数据(如:2008-04-07T14:39:41.02+08:00)格式化成可读的日期(如:2008-04-0714:39:41)
functionrenderDate(value)
{
varreDate=//d{4}/-/d{2}/-/d{2}/gi;
varreTime=//d{2}:/d{2}:/d{2}/gi;
returnvalue.match(reDate)+""+value.match(reTime);
}
</script>
<!--GridPanel 组件的显示位置-->
<divid="grid"style="height:300px;margin:auto;"></div>
从 Web Service 中由 GetArticles 方法返回的是 XML 数据。在将数据绑定到 Ext.data.Store
组件时应使用 Ext.data.XmlReader 而不是网上经常看到的 Ext.data.JsonReader。绑定时我们需要“告诉”
XmlReader 在 XML
数据中哪些节点代表数据条目(本例为“record”),哪个节点代表数据总数(本例为“totalRecords”),以及数据的主键节点
(本例为“Id”)。您可以通过下图来理解 XmlReader 的数据绑定过程:
另外,从上图中的 XML 数据可以看出,日期(Date)的格式比较“丑陋”,如果不加修饰的话将会原样显示于客户的 GridPanel 组件中。因此在客户端显示数据之前,需要对日期数据进行一下加工。在创建 Ext.grid.ColumnModel 时为 Date 列指定 renderer(注意加粗部分):
代码中的“renderDate”是一个 JavaScript 函数,定义如下:
{
varreDate=//d{4}/-/d{2}/-/d{2}/gi;
varreTime=//d{2}:/d{2}:/d{2}/gi;
returnvalue.match(reDate)+""+value.match(reTime);
}
此函数中的 value 参数即为原始的日期数据,由 Ext.grid.ColumnModel 传入。在函数中使用正则表达式分别提取日期数据中的“日期”和“时间”部分,拼接后返回。
整个程序执行后的运行界面如下图所示: