正文
一、查看/修改单行记录
目的:单击某行某个字段,查看/编辑该行详细数据。
1.1 效果截图
1.2 实现代码
后台的代码参见上篇文章:ExtJs 备忘录(6)—— GirdPanl表格(二)[ 搜索分页 ]。
前端代码:7.1.aspx
Ext.onReady( function () {
Ext.QuickTips.init();
Ext.form.Field.prototype.msgTarget = ' side ' ;
var store = new Ext.data.Store({
proxy: new Ext.data.HttpProxy({
url: ' 7.1.aspx?method=search ' ,
method: ' GET '
}),
reader: new Ext.data.JsonReader({
totalProperty: ' count ' ,
root: ' result '
}, [
{ name: ' Name ' },
{ name: ' Id ' },
{ name: ' Email ' },
{ name: ' Gender ' }
])
});
// 加载数据
store.load({
params:{ limit: 10 }
});
var dataColumns = new Ext.grid.ColumnModel({
columns: [
new Ext.grid.RowNumberer(), // 显示行号
{ header: " 编 号 " , dataIndex: ' Id ' , sortable: true },
{ header: " 名 称 " , dataIndex: ' Name ' },
{ header: " 邮 箱 " , dataIndex: ' Email ' },
{ header: " 性 别 " , dataIndex: ' Gender ' ,
renderer: function (value, cell, record) {
// alert(record.data.Age);
var GenderStr = record.data.Gender == 0 ? " 女 " : " 男 " ;
return ' <a href="javascript:void(0);" onclick=javascript:OpenDetailFunc( ' + record.data.Id + ' ," ' + record.data.Name + ' "," ' + record.data.Email + ' ", ' + record.data.Gender + ' ); style="cursor:hand"> ' + GenderStr + ' </a> ' ;
}
}
],
defaults: {
align: ' center '
}
});
// easy-ext.js
var grid = GridPanel(store,dataColumns, 10 , ' <center style="curor:hand" onclick="window.location.reload();">表格查看、修改单行记录|统计</center> ' );
grid.width = 800 ;
grid.render(Ext.getBody());
// -------------------------------------------查看、修改单条记录
var tbId = new NumberField( ' tbId ' , ' 编 号 ' );
var tbName = new TextField( ' tbName ' , ' 名 称 ' );
var tbEmail = new TextField( ' tbEmail ' , ' 邮 箱 ' );
var cbGender = new ComboBox( ' cbGender ' , ' 性 别 ' ,[[ 1 , ' 男 ' ],[ 0 , ' 女 ' ]]);
detailForm = new Ext.FormPanel({
layout: ' form ' ,
frame: true ,
items:[ tbId, tbName, tbEmail, cbGender],
buttons: [
{ text: ' 修 改 ' },
{ text: ' 取 消 ' , handler : function (){ detailWindow.hide(); }}
]
});
// 参数赋值,显示窗体
OpenDetailFunc = function (Id,Name,Email,Gender){
var form = detailForm.getForm();
tbId.value = Id;
tbName.value = Name;
tbEmail.value = Email;
cbGender.value = Gender;
detailWindow.show();
};
detailWindow = new Ext.Window({
title: " 详情 " ,
closable: true ,
iconCls: ' add ' ,
autoWidth: true ,
autoHeight: true ,
buttonAlign: ' center ' ,
closeAction: ' hide ' ,
plain: true ,
// width:400,
// height:380,
items:[detailForm],
listeners: {
' show ' : function (){
this .center(); // 屏幕居中
}
}
});
});
代码说明:
a). GridPanel、NumberField以及ComboBox等参见源代码easyext.js(系列第二篇文章也有专门介绍封装)。
b). 这里仅给出了修改的例子,没有再多些一个显示的,这里考虑的是修改都出来了,显示就不是什么问题了。
二、统计
2.1 在3.0里面之前官方没有正式的统计插件,如需要可以参见本文底部相关文章来写,想想当初要实现这个功能也是大费周章,这里探讨另外一种灵活的形式来实现统计,对于熟悉写后台的人来说比较简单 :)
2.1.1 思路:
前端:只用对增加一行显示就行,比如本来是显示12行,你让他显示13行,需要做特殊处理,比如红字显示统计数据可以在renderer里面做判断处理;
后端:自己写代码统计要统计的数据,然后把这个数据包装一下放到返回显示数据的最后一条。
2.1.2 效果截图
2.1.3 代码片段
主要实现代码(参见源代码7.2.1.aspx.cs):
/// 将数据表转换成JSON类型串
/// </summary>
/// <param name="dt"> 要转换的数据表 </param>
/// <param name="dispose"> 数据表转换结束后是否dispose掉 </param>
/// <returns></returns>
public static StringBuilder DataTableToJson(System.Data.DataTable dt, bool dt_dispose)
{
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.Append( " [ " ); // \r\n
// 数据表字段名和类型数组
string [] dt_field = new string [dt.Columns.Count];
int i = 0 ;
string formatStr = " {{ " ;
string fieldtype = "" ;
foreach (System.Data.DataColumn dc in dt.Columns)
{
dt_field[i] = dc.Caption.Trim(); // ToLower().
formatStr += " ' " + dc.Caption.Trim() + " ': " ; // ToLower().
fieldtype = dc.DataType.ToString().Trim().ToLower();
if (fieldtype.IndexOf( " int " ) > 0 || fieldtype.IndexOf( " deci " ) > 0 ||
fieldtype.IndexOf( " floa " ) > 0 || fieldtype.IndexOf( " doub " ) > 0 ||
fieldtype.IndexOf( " bool " ) > 0 )
{
formatStr += " { " + i + " } " ;
}
else
{
formatStr += " '{ " + i + " }' " ;
}
formatStr += " , " ;
i ++ ;
}
if (formatStr.EndsWith( " , " ))
{
formatStr = formatStr.Substring( 0 , formatStr.Length - 1 ); // 去掉尾部","号
}
formatStr += " }}, " ;
i = 0 ;
object [] objectArray = new object [dt_field.Length];
foreach (System.Data.DataRow dr in dt.Rows)
{
foreach ( string fieldname in dt_field)
{ // 对 \ , ' 符号进行转换
objectArray[i] = dr[dt_field[i]].ToString().Trim().Replace( " \\ " , " \\\\ " ).Replace( " ' " , " \\' " );
switch (objectArray[i].ToString())
{
case " True " :
{
objectArray[i] = " true " ; break ;
}
case " False " :
{
objectArray[i] = " false " ; break ;
}
default : break ;
}
i ++ ;
}
i = 0 ;
stringBuilder.Append( string .Format(formatStr, objectArray));
}
if (stringBuilder.ToString().EndsWith( " , " ))
{
stringBuilder.Remove(stringBuilder.Length - 1 , 1 ); // 去掉尾部","号
}
if (dt_dispose)
{
dt.Dispose();
}
return stringBuilder.Append( " ] " ); // \r\n
}
public override string Search()
{
int start = - 1 ;
int .TryParse(Request.QueryString[ " start " ], out start);
int limit = - 1 ;
int .TryParse(Request.QueryString[ " limit " ], out limit);
string id = Request.QueryString[ " id " ];
IList < User > result = new List < User > ();
if ( string .IsNullOrEmpty(id))
result = GetPage(ConverToList(dataSource.Values), start, limit);
else
{
int uid;
if ( int .TryParse(id, out uid))
{
if (dataSource.ContainsKey(uid))
result.Add(dataSource[uid]);
}
}
// 统计
DataTable dt = new DataTable();
dt.Columns.Add( " Id " );
dt.Columns.Add( " Email " );
dt.Columns.Add( " Name " );
dt.Columns.Add( " Gender " );
dt.Columns.Add( " Age " );
int avg_Age = 0 ;
foreach (User item in result)
{
avg_Age += item.Age;
dt.Rows.Add(item.Id, item.Email, item.Name, item.Gender, item.Age);
}
if (result.Count > 0 )
dt.Rows.Add( "" , "" , "" , "" , string .Format( " 平均:{0} " , avg_Age / result.Count));
return new StringBuilder().Append( " {count: " )
.Append( 1000 )
.Append( " ,result: " )
.Append(DataTableToJson(dt, true ))
// .Append(JavaScriptConvert.SerializeObject(result))
.Append( ' } ' )
.ToString();
}
代码说明:
相比之下我可能更加愿意这种方式进行统计,在后台写代码也好控制,而前端几乎可以不改动就能达到统计的效果。
a). 与1.2例子的后台相比,多增加了一个字段,Age。
b). 这里用的DataTable,因为强类型不好赋值为空,这里也可以返回特定的强类型,比如Id返回-1就表示是统计列,然后在renderer里面做判断显示。
2.2 3.0中的统计插件用
查了一圈,发现还是不支持简单统计,必须分组统计,得使用Ext.data.GroupingStore才行,不过没关系,咱们可以变通:)
2.2.1 截图
2.2.2 实现代码
Ext.QuickTips.init();
Ext.form.Field.prototype.msgTarget = ' side ' ;
var store = new Ext.data.GroupingStore ({
proxy: new Ext.data.HttpProxy({
url: ' 7.2.2.aspx?method=search ' ,
method: ' GET '
}),
reader: new Ext.data.JsonReader({
totalProperty: ' count ' ,
root: ' result '
}, [
{ name: ' Name ' },
{ name: ' Id ' },
{ name: ' Email ' },
{ name: ' Gender ' },
{ name: ' Age ' },
{ name: ' groupField ' ,convert: function (v){ return ' 数据 ' ;} }
]),
sortInfo:{field: ' Age ' , direction: " ASC " },
groupField: ' groupField '
});
// 加载数据
store.load({
params:{ limit: 10 }
});
// 自定义
// Ext.ux.grid.GroupSummary.Calculations['totalCost'] = function(v, record, field){
// return v + (record.data.estimate * record.data.rate);
// };
var summary = new Ext.ux.grid.GroupSummary();
var dataColumns = new Ext.grid.ColumnModel({
columns: [
new Ext.grid.RowNumberer(), // 显示行号
{ header: " 编 号 " , dataIndex: ' Id ' , sortable: true },
{ header: " 名 称 " , dataIndex: ' Name ' },
{ header: " 邮 箱 " , dataIndex: ' Email ' },
{ header: " 性 别 " , dataIndex: ' Gender ' },
{ header: " 数据 " , dataIndex: ' groupField ' },
// max,min,count,sum,average
{ header: " 总年龄 " , dataIndex: ' Age ' ,summaryType: ' average ' }
// ,summaryType:'totalCost',groupable: false
],
defaults: {
align: ' center '
}
});
var grid = new Ext.grid.GridPanel({
store: store,
cm: dataColumns,
renderTo: Ext.getBody(),
autoExpandColumn: 1 ,
autoHeight: true ,
buttonAlign: ' center ' ,
border: true ,
disableSelection: true ,
frame: true ,
loadMask: true ,
width: 800 ,
view: new Ext.grid.GroupingView({
forceFit: true ,
showGroupName: false ,
enableNoGroups: false ,
enableGroupingMenu: false ,
hideGroupedColumn: true
}),
plugins : summary,
// 设置单行选中模式
selModel: new Ext.grid.RowSelectionModel({ singleSelect: true }),
// columnLines: true,//显示列线条
viewConfig: { forceFit: true } // 使列自动均分
});
});
代码说明:
a). 这种办法就是不用服务端来进行统计,支持内置的5种统计,也支持自定义的统计,这个在代码注释里面可以看得到。
b). 这里是通过一个虚拟字段groupField来模拟分组的,这样一来,就能满足基本的统计了。
C). 注意sortInfo与groupField必须配置,然后必须使用Ext.data.GroupingStore。
本文转自over140 51CTO博客,原文链接:http://blog.51cto.com/over140/586538,如需转载请自行联系原作者