最近有朋友在问,如果不使用ajax.net,ajaxpro等等开发包,有没有别的办法写客户端脚本让Repeater实现无刷新分页,答案当然是有的。其他那些开发包无非是帮我们完成好了回发的各种接口,可是,开发包面向的是通用的情况,然不得已需要引入的脚本库有相当的容量,但我们不需要全部,现介绍一种最轻量级的无刷新分页办法(以Repeater为例)。
首先说一下实现的依据,asp.net中有这样一个方法GetCallbackEventReference。它的作用是获取一个对客户端函数的引用;调用该函数时,将启动一个对服务器事件的客户端回调。先可以不用理解透这句话的意思,只需要记住它能获取一段脚本,让客户端调用后实现回发到服务端。废话不多说了,赶紧跟着操作如下:
建立一个WebSite,当然你要用WebProject也无妨,然后增加一个WebForm,假定名为default。
default.aspx内容是
1 <%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default"
2
3 %>
4
5 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
6
7 "http://www./TR/xhtml1/DTD/xhtml1-transitional.dtd">
8 <html xmlns="http://www./1999/xhtml">
9 <head runat="server">
10 <title>CallBack</title>
11
12 <script language="javascript" type="text/javascript">
13 function turnPage(pageIndex){
14 CallServer(pageIndex,'content');
15 }
16
17 function ReceiveCallback(arg,context){
18 var container = document.getElementById(context);
19 //alert(arg + " " + context);
20 container.innerHTML = arg;
21 }
22 </script>
23
24 </head>
25 <body>
26 <form id="form1" runat="server">
27 <div id="content">
28 <asp:Repeater ID="List" runat="server" OnItemDataBound="List_ItemDataBound">
29 <ItemTemplate>
30 <div>
31 用户名:<asp:Label ID="NickName" runat="server"></asp:Label>
32 QQ号:<asp:Label ID="QNumber" runat="server"></asp:Label>
33 </div>
34 </ItemTemplate>
35 </asp:Repeater>
36 </div>
37 <asp:Literal ID="Pager" runat="server"></asp:Literal>
38 </form>
39 </body>
40 </html>
default.aspx.cs内容是
1
using System;
2
using System.Data;
3
using System.Web;
4
using System.Text;
5
using System.Web.UI;
6
using System.Web.UI.HtmlControls;
7
using System.Web.UI.WebControls;
8
using System.IO;
9
using System.Globalization;
10
11
public partial class _Default : System.Web.UI.Page, System.Web.UI.ICallbackEventHandler
12
{
13
//每页显示记录数
14
static int PAGESIZE = 4;
15
DataTable dt = null;
16
private int currentPageIndex;
17
protected void Page_Load(object sender, EventArgs e)
18
{
19
if (!IsPostBack)
20
{
21
BindList(1, true);
22
//获取用于回调的
23
string callbackReference = ClientScript.GetCallbackEventReference(this, "arg",
24
25
"ReceiveCallback", "context", false);
26
string callbackScript = string.Format("function CallServer(arg,context){{ {0}
27
28
}}", callbackReference);
29
ClientScript.RegisterClientScriptBlock(this.GetType(), "CallServer",
30
31
callbackScript, true);
32
33
}
34
}
35
36
/// <summary>
37
/// 绑定列表
38
/// </summary>
39
/// <param name="pageIndex">翻页页码</param>
40
/// <param name="needRender">是否需要重画分页面码</param> 41
protected void BindList(int pageIndex, bool needRender)
42
{
43
DataTable dt = GetData();
44
//计算总页数
45
int pages = (dt.Rows.Count % PAGESIZE == 0) ? dt.Rows.Count / PAGESIZE :
46
47
(dt.Rows.Count / PAGESIZE) + 1;
48
if (needRender)
49
RenderPager(pages);
50
51
if (pageIndex > pages)
52
pageIndex = pages;
53
else if (pageIndex < 1)
54
pageIndex = 1;
55
int startId = (pageIndex - 1) * PAGESIZE + 1;
56
int endId = pageIndex * PAGESIZE;
57
58
DataRow[] rows = dt.Select(string.Format("id>={0} and id<={1}", startId, endId));
59
List.DataSource = rows;
60
List.DataBind();
61
}
62
63
/// <summary>
64
/// 画出分页页码
65
/// </summary>
66
/// <param name="pages"></param> 67
protected void RenderPager(int pages)
68
{
69
StringBuilder sb = new StringBuilder();
70
int pageIndex = 1;
71
do
72
{
73
sb.AppendFormat("<a href='javascript:turnPage({0});'>{0}</a> ",
74
75
pageIndex);
76
} while (pageIndex++ < pages);
77
78
Pager.Text = sb.ToString();
79
}
80
81
/// <summary>
82
/// 初始化一个DataTable作数据源
83
/// </summary> 84
protected DataTable GetData()
85
{
86
if (null == Cache["Data"])
87
{
88
dt = new DataTable();
89
dt.Columns.Add("ID", typeof(int));
90
dt.Columns.Add("NickName", typeof(string));
91
dt.Columns.Add("QNumber", typeof(string));
92
93
DataRow row = dt.NewRow();
94
row["ID"] = 1;
95
row["NickName"] = "人物1";
96
row["QNumber"] = "21243468";
97
dt.Rows.Add(row);
98
99
row = dt.NewRow();
100
row["ID"] = 2;
101
row["NickName"] = "人物2";
102
row["QNumber"] = "9058307";
103
dt.Rows.Add(row);
104
105
row = dt.NewRow();
106
row["ID"] = 3;
107
row["NickName"] = "人物3";
108
row["QNumber"] = "21243468";
109
dt.Rows.Add(row);
110
111
row = dt.NewRow();
112
row["ID"] = 4;
113
row["NickName"] = "人物4";
114
row["QNumber"] = "22526451";
115
dt.Rows.Add(row);
116
117
row = dt.NewRow();
118
row["ID"] = 5;
119
row["NickName"] = "人物5";
120
row["QNumber"] = "254852182";
121
dt.Rows.Add(row);
122
123
row = dt.NewRow();
124
row["ID"] = 6;
125
row["NickName"] = "人物6";
126
row["QNumber"] = "81461006";
127
dt.Rows.Add(row);
128
129
row = dt.NewRow();
130
row["ID"] = 7;
131
row["NickName"] = "人物7";
132
row["QNumber"] = "375772376";
133
dt.Rows.Add(row);
134
135
row = dt.NewRow();
136
row["ID"] = 8;
137
row["NickName"] = "人物8";
138
row["QNumber"] = "153534649";
139
dt.Rows.Add(row);
140
141
row = dt.NewRow();
142
row["ID"] = 9;
143
row["NickName"] = "人物9";
144
row["QNumber"] = "619468";
145
dt.Rows.Add(row);
146
147
row = dt.NewRow();
148
row["ID"] = 10;
149
row["NickName"] = "人物10";
150
row["QNumber"] = "83223563";
151
dt.Rows.Add(row);
152
153
Cache["Data"] = dt;
154
}
155
else
156
{
157
dt = Cache["Data"] as DataTable;
158
}
159
return dt;
160
}
161
162
实现ICallbackEventHandler 成员RaiseCallbackEvent
176
177
protected void List_ItemDataBound(object sender, RepeaterItemEventArgs e)
178
{
179
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType ==
180
181
ListItemType.AlternatingItem)
182
{
183
Label NickName = e.Item.FindControl("NickName") as Label;
184
Label QNumber = e.Item.FindControl("QNumber") as Label;
185
186
DataRow row = e.Item.DataItem as DataRow;
187
NickName.Text = row["NickName"].ToString();
188
QNumber.Text = row["QNumber"].ToString();
189
}
190
}
191
192
/// <summary>
193
/// 获取指定控件重画的内容
194
/// </summary>
195
/// <param name="control"></param>
196
/// <returns></returns>197
private string RenderControl(Control control)
198
{
199
StringWriter writer1 = new StringWriter(CultureInfo.InvariantCulture);
200
HtmlTextWriter writer2 = new HtmlTextWriter(writer1);
201
202
control.RenderControl(writer2);
203
writer2.Flush();
204
writer2.Close();
205
206
return writer1.ToString();
207
}
208
}
正如代码所示,需要实现ICallbackEventHandler接口的两个方法,RaiseCallbackEvent用于接收到客户端传回来的参数,GetCallbackResult是在服务端做出合适的反应后将指定的结果发送回客户端,这里是把repeater重画的内容返回了,然后在客户端ReceiveCallback函数里进行无刷新的最后展现,最想说明的是,一定要注意CallServer(pageIndex,'content');ReceiveCallback(arg,context);这两个函数的使用技巧,CallServer是服务端生成的,它的第二个参数直接决定了在什么地方无刷新,ReceiveCallback和前者都是context参数,内容就是相同的,相当于传到服务器再原封不动的传回来,因此用于回发和接收时共享数据。
小示例可变换多种实现,希望大家都能找到适合自己简便实现的办法。