[原创]ExtAspNet秘密花园(十六) — 表格之排序与分页
排序和分页是表格必备的两个重要功能,本章会详细阐述如何在ExtAspNet中实现这两个功能。
排序
首先来看一个排序的例子,ASPX标签如下:
1: <ext:Grid ID="Grid1" Title="表格" AllowSorting="true" SortColumn="year"
2: SortDirection="ASC" Width="750px" AutoHeight="true" runat="server" EnableCheckBoxSelect="True"
3: DataKeyNames="Id,Name,AtSchool" EnableRowNumber="True" OnSort="Grid1_Sort">
4: <Columns>
5: <ext:BoundField Width="100px" ColumnID="name" SortField="Name" DataField="Name" DataFormatString="{0}"
6: HeaderText="姓名" />
7: <ext:TemplateField Width="60px" SortField="Gender" HeaderText="性别">
8: <ItemTemplate>
9: <asp:Label ID="Label2" runat="server" Text='<%# GetGender(Eval("Gender")) %>'></asp:Label>
10: </ItemTemplate>
11: </ext:TemplateField>
12: <ext:BoundField Width="100px" ColumnID="year" SortField="EntranceYear" DataField="EntranceYear" HeaderText="入学年份" />
13: <ext:CheckBoxField Width="60px" SortField="AtSchool" RenderAsStaticField="true" DataField="AtSchool"
14: HeaderText="是否在校" />
15: <ext:HyperLinkField HeaderText="所学专业" DataToolTipField="Major" DataTextField="Major"
16: DataTextFormatString="{0}" DataNavigateUrlFields="Major" DataNavigateUrlFormatString="http://gsa.ustc.edu.cn/search?q={0}"
17: DataNavigateUrlFieldsEncode="true" Target="_blank" ExpandUnusedSpace="True" />
18: <ext:ImageField Width="60px" DataImageUrlField="Group" DataImageUrlFormatString="~/images/16/{0}.png"
19: HeaderText="分组"></ext:ImageField>
20: </Columns>
21: </ext:Grid>
这里面有几个关键点:
- 表格控件设置排序相关的属性以及OnSort事件处理函数
- AllowSorting:是否允许排序。
- SortColumn:当前排序的列ID,当然也可以不设置此属性,而是在后台初始化代码中直接指定默认排序字段。
- SortDirection:排序方向,ASC(默认值)或者DESC。
- 对于每一个需要排序的列,设置SortField属性。
来看下后台表格初始化代码:
1: protected void Page_Load(object sender, EventArgs e)
2: {
3: if (!IsPostBack)
4: {
5: BindGrid();
6: }
7: }
8:
9: private void BindGrid()
10: {
11: GridColumn column = Grid1.FindColumn(Grid1.SortColumn);
12: BindGridWithSort(column.SortField, Grid1.SortDirection);
13: }
14:
15: private void BindGridWithSort(string sortField, string sortDirection)
16: {
17: DataTable table = GetDataTable();
18:
19: DataView view1 = table.DefaultView;
20: view1.Sort = String.Format("{0} {1}", sortField, sortDirection);
21:
22: Grid1.DataSource = view1;
23: Grid1.DataBind();
24: }
注意,在调用BindGridWithSort私有函数时,我们通过FindColumn找到默认排序的列,从而找到此列的排序数据字段。
当然,如果没有设置表格的SortColumn,这里可以直接硬编码默认的排序字段,比如:
1: private void BindGrid()
2: {
3: BindGridWithSort("EntranceYear", Grid1.SortDirection);
4: }
最后是用户点击列标题时触发的排序事件,来看下其事件处理函数:
1: protected void Grid1_Sort(object sender, ExtAspNet.GridSortEventArgs e)
2: {
3: BindGridWithSort(e.SortField, e.SortDirection);
4: }
是不是非常简单,最后的显示效果如下:
内存分页
所谓的内存分页,就是在页面初始化时将表格数据一次性全部载入,保存在页面状态视图中,从而保证在后续的分页操作时不用再次访问数据库。在数据量少的情况下(一般少于100条数据),这一方式非常划算,因此需要的编码非常少。下面还是通过一个示例来说明。
先来看下ASPX标签的结构:
1: <ext:Grid ID="Grid1" Title="表格" PageSize="5" ShowBorder="true" ShowHeader="true"
2: AutoHeight="true" AllowPaging="true" runat="server" EnableCheckBoxSelect="True"
3: Width="800px" DataKeyNames="Id,Name" OnPageIndexChange="Grid1_PageIndexChange"
4: EnableRowNumber="True">
5: <Columns>
6: <ext:BoundField Width="100px" DataField="Name" DataFormatString="{0}" HeaderText="姓名" />
7: <ext:TemplateField Width="60px" HeaderText="性别">
8: <ItemTemplate>
9: <asp:Label ID="Label2" runat="server" Text='<%# GetGender(Eval("Gender")) %>'></asp:Label>
10: </ItemTemplate>
11: </ext:TemplateField>
12: <ext:BoundField Width="60px" DataField="EntranceYear" HeaderText="入学年份" />
13: <ext:CheckBoxField Width="60px" RenderAsStaticField="true" DataField="AtSchool" HeaderText="是否在校" />
14: <ext:HyperLinkField HeaderText="所学专业" DataTooltipField="Major" DataTextField="Major"
15: DataTextFormatString="{0}" DataNavigateUrlFields="Major" DataNavigateUrlFormatString="http://gsa.ustc.edu.cn/search?q={0}" DataNavigateUrlFieldsEncode="true"
16: Target="_blank" ExpandUnusedSpace="True" />
17: <ext:ImageField Width="60px" DataImageUrlField="Group" DataImageUrlFormatString="~/images/16/{0}.png"
18: HeaderText="分组"></ext:ImageField>
19: </Columns>
20: </ext:Grid>
这里面有几个关键点:
- 表格设置属性AllowPaging=true和PageSize;
- 表格设置分页事件处理函数OnPageIndexChange;
- 各列没有特殊的属性设置。
看下后台初始化代码:
1: protected void Page_Load(object sender, EventArgs e)
2: {
3: if (!IsPostBack)
4: {
5: BindGrid();
6: }
7: }
8:
9: private void BindGrid()
10: {
11: DataTable table = GetDataTable();
12:
13: Grid1.DataSource = table;
14: Grid1.DataBind();
15: }
可以看到,初始化代码和不分页时的代码一模一样。
再来看下分页事件处理函数:
1: protected void Grid1_PageIndexChange(object sender, ExtAspNet.GridPageEventArgs e)
2: {
3: Grid1.PageIndex = e.NewPageIndex;
4: }
也很简单,对吧。
其实,如果你之前用过AspNet的GridView的话,这里的代码和使用GridView的代码一模一样。
数据库分页
在展示大数据时,数据库分页是必须的。数据库分页时,页面第一次初始化时只加载表格当前页的数据,所以每次用户点击分页按钮时,后台代码都要进行数据库查询并重新绑定当前页的数据。由于查询当前页的数据并绑定表格需要反复调用,通常我们把这一操作提取到一个单独的函数中。
首先看下ASPX标签的声明:
1: <ext:Grid ID="Grid1" Title="表格" Width="800px" PageSize="5" ShowBorder="true" ShowHeader="true"
2: AutoHeight="true" AllowPaging="true" runat="server" EnableCheckBoxSelect="True"
3: DataKeyNames="Id,Name" IsDatabasePaging="true" OnPageIndexChange="Grid1_PageIndexChange"
4: EnableRowNumber="True">
5: <Columns>
6: <ext:BoundField Width="100px" DataField="Name" DataFormatString="{0}" HeaderText="姓名" />
7: <ext:TemplateField Width="60px" HeaderText="性别">
8: <ItemTemplate>
9: <asp:Label ID="Label2" runat="server" Text='<%# GetGender(Eval("Gender")) %>'></asp:Label>
10: </ItemTemplate>
11: </ext:TemplateField>
12: <ext:BoundField Width="60px" DataField="EntranceYear" HeaderText="入学年份" />
13: <ext:CheckBoxField Width="60px" RenderAsStaticField="true" DataField="AtSchool" HeaderText="是否在校" />
14: <ext:HyperLinkField HeaderText="所学专业" DataTooltipField="Major" DataTextField="Major"
15: DataTextFormatString="{0}" DataNavigateUrlFields="Major" DataNavigateUrlFormatString="http://gsa.ustc.edu.cn/search?q={0}" DataNavigateUrlFieldsEncode="true"
16: Target="_blank" ExpandUnusedSpace="True" />
17: <ext:ImageField Width="60px" DataImageUrlField="Group" DataImageUrlFormatString="~/images/16/{0}.png"
18: HeaderText="分组"></ext:ImageField>
19: </Columns>
20: </ext:Grid>
这里面有几个关键点:
- 表格设置属性AllowPaging、IsDatabasePaging、PageSize三个属性;
- 表格设置分页事件处理函数OnPageIndexChange;
- 各列没有特殊的属性设置。
看下后台初始化代码:
1: protected void Page_Load(object sender, EventArgs e)
2: {
3: if (!IsPostBack)
4: {
5: BindGrid();
6: }
7: }
8:
9: private void BindGrid()
10: {
11: // 1.设置总项数
12: Grid1.RecordCount = GetTotalCount();
13:
14: // 2.获取当前分页数据
15: DataTable table = GetPagedDataTable(Grid1.PageIndex, Grid1.PageSize);
16:
17: // 3.绑定到Grid
18: Grid1.DataSource = table;
19: Grid1.DataBind();
20: }
可以看出初始化表格数据需要如下几个步骤:
- 设置表格的RecordCount属性,告诉表格总记录数;
- 根据表格的PageIndex(默认是0)和PageSize属性,从数据库查询本页的数据;
- 将查询到的本页数据绑定到表格。
由此可以看出,表格必须知道如下四种数据后,才能正确显示:
- 当前是第几页(PageIndex);
- 总共有多少条数据(RecordCount);
- 每页显示多少条数据(PageSize);
- 当前页的数据是什么(DataSource)。
再来看下分页事件处理函数:
1: protected void Grid1_PageIndexChange(object sender, ExtAspNet.GridPageEventArgs e)
2: {
3: Grid1.PageIndex = e.NewPageIndex;
4:
5: BindGrid();
6: }
首先告诉表格接下来应该显示哪一页,然后重新查询数据库并绑定当前页的数据。
界面显示效果和内存分页时一样,就不再截图。
为什么说内存分页在大数据时性能差?
其实原因前面已经提到了,主要是因为内存分页时会把所有表格数据保存到页面的状态视图中(ViewState),导致页面大小迅速增加,从而增加网络下载上载的时间,并且减慢了页面的渲染速度。
虽然ExtAspNet放弃了在ViewState中保存数据,从而可以在Ajax的环境中减少网络的数据传输量,但是内存分页时所有的表格数据还是要保存下来,供下次分页时使用。
拿本篇文章中的内存分页示例,在用户点击下一页时,通过FireBug可以看到这次HTTP Post请求:
其中X_STATE就是ExtAspNet保存控件状态的地方,把全部X_STATE的内容拷贝下来,并执行如下JavaScript代码:
1: var xstate = JSON.parse(Base64.decode('eyJHcmlk...FtdXX19'));
2: var values = xstate.Grid1.X_Rows.Values;
3: values.length + '\r\n' + JSON.stringify(values);
可以看到如下的执行结果:
由此可见,全部的11条数据在每次页面回发时都会作为HTTP Post的参数上传到服务器,从而在大数据量的情况下导致页面性能急剧下降。
小结
排序和分页是表格的最基本操作,也是每个程序员都应该熟练掌握的知识。特别是处理大量数据(一般大于100条)一定要使用数据库分页,否则页面性能会非常差。下一篇文章我们会讨论ExtAspNet对表格的扩展列,包括序号列、选择框列、行扩展列、模拟树列以及弹出窗体列。
注:《ExtAspNet秘密花园》系列文章由三生石上原创,博客园首发,转载请注明出处。文章目录 官方论坛
[原创]ExtAspNet秘密花园(十六) — 表格之排序与分页相关推荐
- [原创]ExtAspNet秘密花园(二) — 一切从头开始
原文地址为: [原创]ExtAspNet秘密花园(二) - 一切从头开始 这篇文章我们会从头开始使用ExtAspNet,最终完成一个模拟用户登录的界面,最终的效果图如下所示: 项目准备 1. 新建一个 ...
- Java网络商城项目 SpringBoot+SpringCloud+Vue 网络商城(SSM前后端分离项目)十六(商品排序,Thymeleaf快速入门,商品详情页的展示)
Java网络商城项目 SpringBoot+SpringCloud+Vue 网络商城(SSM前后端分离项目)十六(商品详情页的展示) 一.商品排序 1.完善页面信息 这是用来做排序的,默认按照综合排序 ...
- linux cma内存,【原创】(十六)Linux内存管理之CMA,
[原创](十六)Linux内存管理之CMA, 背景 Read the fucking source code! --By 鲁迅 A picture is worth a thousand words. ...
- [原创]ExtAspNet秘密花园(二) mdash; 一切从头开始
这篇文章我们会从头开始使用ExtAspNet,最终完成一个模拟用户登录的界面,最终的效果图如下所示: 项目准备 1. 新建一个ASP.NET Web应用程序项目. 2. 从开源网站下载最新版本的Ext ...
- [原创]FineUI秘密花园(六) — 表单控件
FineUI中有哪些常用的表单控件,它们有什么共同点和不同点,这一篇文章我们会详细解说. 表单控件的公共属性 所有的表单都具有如下属性: ShowLabel:是否显示标签(默认值:true). Sho ...
- 十六、希尔排序即其优化(交换法--->移动法)
一.为何要引入希尔排序 首先先看直接插入排序所存在的弊端,数组 arr = {2,3,4,5,6,1},如果要插入的数1(最小),这样的过程是: {2,3,4,5,6,6} {2,3,4,5,5,6} ...
- linux 内存 cma,【原创】(十六)Linux内存管理之CMA
背景 Read the fucking source code! --By 鲁迅 A picture is worth a thousand words. --By 高尔基 说明: Kernel版本: ...
- angular ts 表格_Angular2表格/可排序/table
Angular2表格 1. 官网下载Angular2开发环境,以及给出的quickstart代码示例demo(地址如下),具体步骤不在详述. https://github.com/angular/qu ...
- SAP UI5 应用开发教程之六十六 - 基于 OData V4 的 SAP UI5 表格控件如何实现删除功能试读版
一套适合 SAP UI5 初学者循序渐进的学习教程 教程目录 SAP UI5 本地开发环境的搭建 SAP UI5 应用开发教程之一:Hello World SAP UI5 应用开发教程之二:SAP U ...
最新文章
- 在CentOS 6.9 x86_64的nginx 1.12.2上开启标准模块ngx_http_auth_request_module实录
- velocity mybatis spring 在maven的整合开发(二)
- QListWidget读取本地文件夹中文件并显示名字,双击读取xml数据
- 更多传媒巨头或进军大数据产业
- C# 线程手册 第一章 线程定义 .NET 和 C# 对线程的支持
- 训练日志 2018.9.8
- linux中date使用方法,linux命令详解date使用方法(计算母亲节和父亲节日期脚本示例)...
- Android学习笔记(一)——控件布局常用属性
- JAVA中输出姓王的姓名,没出过国的人,不配姓王
- 论文重复率一般要求是多少?
- WIN7下建行捷德U盾支付
- Python 一键导出微信读书的书籍和笔记
- 心回暖------振作
- 手机照片丢失怎么才能恢复
- python3下安装h5py
- 从区块链到DAG(五)--DAG项目介绍IOTA和Obyte
- 图像分析之曲率滤波(困惑篇)
- Java版本工程行业管理系统源码-专业的工程管理软件-提供一站式服务
- JavaScript幸运大转盘
- .NET周报 【4月第4期 2023-04-23】
热门文章
- 让协同工作更加轻松——Office 2007面面观之(8)
- forms oracle runtime_FRM-92101:forms Server在启动过程中失败
- Xamarin图表开发基础教程(11)OxyPlot框架支持的图表类型
- 网络防嗅探工具SniffJoke
- SQL Server 2014图文安装教程
- 用户未登录重定向到登录界面_Linux 用户登录记录
- js layui 弹出子窗体_Layui中JS实现弹出层的应用
- linux sed 慢,echo/awk/sed的性能问题
- 苹果发布会证实,他们把脸部检测技术和ARKit结合在了一起
- 百度计算生物研究登上Nature子刊!将3D结构引入分子表征,结果超越斯坦福MIT,已落地制药领域...