ajax library的客户端基本库里提供了异步访问服务端页面的脚本方法,很好的封装了xmlHttpRequest的常用方法,并与aspnet的方法实现了无缝的集成,很方便的在客户端异步的调用服务器的方法。利用这些脚本方法,仅仅从服务器端返回纯粹的数据,最终的如何显示这些数据由客户端完成。不像ajax.net里的那些服务器控件,比如updatepanel包装下的控件。虽然是无刷新了,但是最终控件的生成还是由服务器端完成,然后成堆的返回到客户端,服务器的负担还是没减少。
分页是我们常用的显示数据的操作,按照原来aspnet的服务器控件模式,datagrid包办了获取数据和分页的操作,而用客户端脚本,只需要服务器提供数据即可,下面用客户端脚本完成在客户端的分页功能。这种分页的基本步骤是,客户端首先从服务器那获取总记录数,然后计算分页信息,翻页的时候将页码和页面大小发送到服务器,服务器返回符合要求的记录。
\n
服务器端的方法
1/**//// <summary>
2 /// 总记录数
3 /// </summary>
4 private static int recordCount = 0;
5
6 /**//// <summary>
7 /// 获取分页数据,其中book为自定义的类
8 /// 实际应该传入查询参数,这里只是简单模拟
9 /// </summary>
10 /// <param name=”pageSize”>页面大小</param>
11 /// <param name=”pageIndex”>当前页</param>
12 /// <returns></returns>
13 [GenerateScriptType(typeof(Book))]
14 [WebMethod]
15 public static IList<Book> GetBookList(int pageSize, int pageIndex)
16 {
17 // 模拟从数据库返回结果
18 int starRow = pageSize * pageIndex + 1;
19 int endRow = pageSize * (pageIndex + 1);
20
21 if (starRow > recordCount)
22 {
23 starRow = starRow – pageSize;
24 }
25
26 if (endRow > recordCount)
27 {
28 endRow = recordCount;
29 }
30
31 IList<Book> books = new List<Book>();
32
33 for (int i = starRow; i <= endRow; i++)
34 {
35 Book book = new Book(“book” + i, “isbn” + i);
36 books.Add(book);
37 }
38
39 return books;
40 }
41
42 /**//// <summary>
43 /// 实际情况应该是从数据库获取总记录数,并且需要有传入参数
44 /// 这里只随机返回一个数字
45 /// </summary>
46 /// <returns></returns>
47 [WebMethod]
48 public static int GetListCount()
49 {
50 recordCount = new Random(DateTime.Now.Millisecond).Next(1, 10000);
51 return recordCount;
52 }
客户端脚本
1<script language=”javascript” type=”text/javascript”>
2 // 当前页
3 var currentPageIndex = 0;
4 // 总记录数
5 var recordCount = 0;
6 // 总页数
7 var pageCount = 0;
8 // 页面初始大小
9 var pageSize = 10;
10
11 function pageLoad()
12 {
13 // 调用页面的方法获取总记录数
14 PageMethods.GetListCount(onGetListCount);
15 }
16
17 function onGetListCount(result, context, MethodName)
18 {
19 // 处理记录数,计算总页数
20 recordCount = result;
21 calculatePageCount();
22
23 // 调用页面方法获取分页记录
24 PageMethods.GetBookList(pageSize, currentPageIndex, onGetBookListSucceeded);
25 }
26
27 // 计算页数
28 function calculatePageCount()
29 {
30 pageCount = recordCount / pageSize;
31 if (recordCount % pageSize != 0)
32 {
33 pageCount++;
34 pageCount = Math.floor(pageCount);
35 }
36 }
37
38 // 处理服务端返回的查询记录
39 function onGetBookListSucceeded(result, context, methodName)
40 {
41 var contentBuilder = new Sys.StringBuilder(“<table border=’1′ width=’100%’><tr><td>book name</td><td>ISBN</td></tr>”);
42 for (var i = 0; i < result.length; i++)
43 {
44 contentBuilder.appendLine(String.format(“<tr><td>{0}</td><td>{1}</td></tr>”, result[i].Name, result[i].ISBN));
45 }
46 contentBuilder.appendLine(“</table>”);
47 contentBuilder.appendLine(createPageNavigation());
48 get(“divRecords”).innerHTML = contentBuilder.toString();
49 }
50
51 // 生成分页页脚分页信息
52 function createPageNavigation()
53 {
54 var pageNaviBuilder = new Sys.StringBuilder(“<div class=’page’>”);
55 var firstPage = “<a><font face=’webdings’ title=’首页’ class=’navigator’ onclick=’toPage(0)’>9</font></a> ”;
56
57 var previousPage = “<a onclick=’toPage(–currentPageIndex)’ class=’navigator’><font face=’webdings’ title=’上一页’>7</font></a>”;
58 if (currentPageIndex == 0)
59 {
60 previousPage = “<a disabled><font face=’webdings’ title=’上一页’>7</font></a>”;
61 }
62
63 var nextPage = “<a onclick=’toPage(++currentPageIndex)’ class=’navigator’><font face=’webdings’ title=’下一页’>8</font></a>”;
64 if (currentPageIndex == pageCount – 1)
65 {
66 nextPage = “<a disabled><font face=’webdings’ title=’下一页’>8</font></a>”;
67 }
68
69 var lastPage = “<a onclick=’toPage(pageCount – 1)’ class=’navigator’><font face=’webdings’ title=’末页’>:</font></a>”;
70
71 pageNaviBuilder.appendLine(String.format(“第{0}页/共{1}页 共{2}条记录 ”, currentPageIndex + 1, pageCount, recordCount));
72 pageNaviBuilder.appendLine(createPageSizeList());
73 pageNaviBuilder.appendLine(firstPage);
74 pageNaviBuilder.appendLine(previousPage);
75 pageNaviBuilder.appendLine(nextPage);
76 pageNaviBuilder.appendLine(lastPage);
77
78 return pageNaviBuilder.toString();
79 }
80
81 // 生成页面大小的下拉选择列表
82 function createPageSizeList()
83 {
84 var pageSizeBuilder = new Sys.StringBuilder(“每页<select onchange=’onPageSizeChanged(this)’>”);
85 // 生成下拉选项
86 for (var i = 1; i <=5; i++)
87 {
88 if (i * 10 != pageSize)
89 {
90 pageSizeBuilder.appendLine(String.format(“<option value=’{0}’>{0}</option>”, i * 10));
91 }
92 else
93 {
94 // 设置选中项为当前的页面大小
95 pageSizeBuilder.appendLine(String.format(“<option selected value=’{0}’>{0}</option>”, i * 10));
96 }
97 }
98 pageSizeBuilder.appendLine(“</select>行 ”);
99 return pageSizeBuilder.toString();
100 }
101
102 // 给定指定页数获取分页数据
103 function toPage(pageIndex)
104 {
105 if (pageIndex >=0 & pageIndex <= pageCount – 1)
106 {
107 PageMethods.GetBookList(pageSize, pageIndex, onGetBookListSucceeded);
108 currentPageIndex = pageIndex
109 }
110 }
111
112 // 改变页面大小时重新计算页面大小和设置当前页
113 function onPageSizeChanged(sender)
114 {
115 var newPageSize = parseInt(sender.options[sender.selectedIndex].innerText);
116
117 var newPageIndex = (currentPageIndex + 1) * pageSize / newPageSize – 1;
118 if ((currentPageIndex + 1) * pageSize % newPageSize != 0)
119 {
120 newPageIndex++;
121 newPageIndex = Math.floor(newPageIndex);
122 }
123
124 currentPageIndex = newPageIndex;
125 pageSize = newPageSize;
126
127 calculatePageCount();
128
129 if (currentPageIndex > pageCount – 1)
130 {
131 currentPageIndex = pageCount – 1;
132 }
133
134 PageMethods.GetBookList(pageSize, currentPageIndex, onGetBookListSucceeded);
135 }
136
137 </script>
还可以加入加载等待的页面,以及美化一下。另外这里没有实际访问数据库,也没有传入参数,这些都可以扩展,觉得比较适用于显示固定记录数或变动不大的查询。