您的位置:首页 > 其它

客户端脚本简单实现Repeater的无刷新分页

2011-11-28 14:00 537 查看
/article/5988794.html
Repeater无刷新分页
2011-01-28 19:14

Repeater分页功能我就不说了,网上这样的例子很多。而且本来想放在《Repeater控件里的大智慧》里面,但这个内容相当的多,而且内容很晦涩。所以就提出来单独来说。

这个方法是我从网上看到了,这里我就是和大家一起来分析下这些代码。当弄懂以后,就可以根据自己的情况来写代码了。(我也将穿插一些我修改后的代码,以作参考。)

下面我先给大家一段我看到网上提供的完整代码。复制过去就可以直接运行了。

代码地址:/article/5988794.html

建议大家把这些代码复制过去,然后运行跟踪下整个流程。等自己对这些代码有一定的了解时,再来看我写的注释。否则,看是很难看懂的。

前台关键就是这些脚本。仅仅看前台代码是看不出前台调用了这些脚本,所以后台代码才是我们所要掌握的重点。

前台:

<html xmlns="http://www.w3.org/1999/xhtml">

<head id="Head1" runat="server">

<title>CallBack</title>

<script language="javascript" type="text/javascript">

function turnPage(pageIndex) {

CallServer(pageIndex, 'content');

}

function ReceiveCallback(arg, context) {

var container = document.getElementById(context);

//alert(arg + " " + context); //有兴趣你可以看看运行时到底显示什么东西

container.innerHTML = arg;

}

</script>

</head>

<body>

<form id="form1" runat="server">

<div id="content">

<asp:Repeater ID="List" runat="server" OnItemDataBound="List_ItemDataBound">

<ItemTemplate>

<div>

用户名:<asp:Label ID="NickName" runat="server"></asp:Label>

QQ号:<asp:Label ID="QNumber" runat="server"></asp:Label>

</div>

</ItemTemplate>

</asp:Repeater>

</div>

<asp:Literal ID="Pager" runat="server"></asp:Literal>

</form>

</body>

</html>

后台:

using System;

using System.Data;

using System.Web;

using System.Text;

using System.Web.UI;

using System.Web.UI.HtmlControls;

using System.Web.UI.WebControls;

using System.IO;

using System.Globalization;

namespace WebApplication4

{

public partial class _Default : System.Web.UI.Page, System.Web.UI.ICallbackEventHandler

{

//每页显示记录数

static int PAGESIZE = 4;

DataTable dt = null;

private int currentPageIndex;

protected void Page_Load(object sender, EventArgs e)

{

if (!IsPostBack)

{

BindList(1, true); //绑定数据

//获取用于回调的

string callbackReference = ClientScript.GetCallbackEventReference(this, "arg", "ReceiveCallback", "content", false);

string callbackScript = string.Format("function CallServer(arg,content){{ {0} }}", callbackReference);

ClientScript.RegisterClientScriptBlock(this.GetType(), "CallServer", callbackScript, true);

//这3条语句你都可以不要修改直接照抄,功能是将后台的代码直接注册到前台中并执行。

}

}

/**/

/// <summary>

/// 绑定列表

/// </summary>

/// <param name="pageIndex">翻页页码</param>

/// <param name="needRender">是否需要重画分页面码</param>

protected void BindList(int pageIndex, bool needRender)

{

DataTable dt = GetData(); //获取数据

//计算总页数

int pages = (dt.Rows.Count % PAGESIZE == 0) ? dt.Rows.Count / PAGESIZE :(dt.Rows.Count / PAGESIZE) + 1;

if (needRender) //true 执行

RenderPager(pages); //绘制出分页

if (pageIndex > pages)//似乎没用

pageIndex = pages;

else if (pageIndex < 1)

pageIndex = 1;

int startId = (pageIndex - 1) * PAGESIZE + 1; //起始页

int endId = pageIndex * PAGESIZE; //末尾页

DataRow[] rows = dt.Select(string.Format("ID>={0} and ID<={1}", startId, endId));

List.DataSource = rows;

List.DataBind();

//这里是数据的绑定,如果你一直按照他的思路,那你就完了,因为原作者是自己临时写的数据源,而你的数据源是在数据库中

//所以修改代码是必须的。这里用到了分页的类PagedDataSource

// DataTable dt = GetData(); //获取数据

// //计算总页数

// int pages = (dt.Rows.Count % PAGESIZE == 0) ? dt.Rows.Count / PAGESIZE : (dt.Rows.Count / PAGESIZE) + 1;

// if (needRender)

// {

// RenderPager(pages); //绘制出分页

// }

// PagedDataSource pds = new PagedDataSource();

// pds.DataSource = questionTable.DefaultView;

// pds.AllowPaging = true;

// pds.PageSize = 5;

// if (pageIndex == 0)

// {

// pageIndex = 1;

// }

//设置分页对象的当前索引

// pds.CurrentPageIndex = pageIndex - 1; //由这个控制分页显示的数据内容

// test.DataSource = pds;

// test.DataBind();

}

/**/

/// <summary>

/// 画出分页页码 大家用时都可以不用修改了

/// </summary>

/// <param name="pages"></param>

protected void RenderPager(int pages)

{

StringBuilder sb = new StringBuilder();

int pageIndex = 1;

do

{

sb.AppendFormat("<a href='javascript:turnPage({0});'>{0}</a>  ",pageIndex);

} while (pageIndex++ < pages);

Pager.Text = sb.ToString();

}

/**/

/// <summary>

/// 初始化一个DataTable作数据源 就是获取数据并以DataTable形式返回 以便BindList调用

/// </summary>

protected DataTable GetData()

{

if (null == Cache["Data"])

{

dt = new DataTable();

dt.Columns.Add("ID", typeof(int));

dt.Columns.Add("NickName", typeof(string));

dt.Columns.Add("QNumber", typeof(string));

DataRow row = dt.NewRow();

row["ID"] = 1;

row["NickName"] = "人物1";

row["QNumber"] = "21243468";

dt.Rows.Add(row);

row = dt.NewRow();

row["ID"] = 2;

row["NickName"] = "人物2";

row["QNumber"] = "9058307";

dt.Rows.Add(row);

row = dt.NewRow();

row["ID"] = 3;

row["NickName"] = "人物3";

row["QNumber"] = "21243468";

dt.Rows.Add(row);

row = dt.NewRow();

row["ID"] = 4;

row["NickName"] = "人物4";

row["QNumber"] = "22526451";

dt.Rows.Add(row);

row = dt.NewRow();

row["ID"] = 5;

row["NickName"] = "人物5";

row["QNumber"] = "254852182";

dt.Rows.Add(row);

row = dt.NewRow();

row["ID"] = 6;

row["NickName"] = "人物6";

row["QNumber"] = "81461006";

dt.Rows.Add(row);

row = dt.NewRow();

row["ID"] = 7;

row["NickName"] = "人物7";

row["QNumber"] = "375772376";

dt.Rows.Add(row);

row = dt.NewRow();

row["ID"] = 8;

row["NickName"] = "人物8";

row["QNumber"] = "153534649";

dt.Rows.Add(row);

row = dt.NewRow();

row["ID"] = 9;

row["NickName"] = "人物9";

row["QNumber"] = "619468";

dt.Rows.Add(row);

row = dt.NewRow();

row["ID"] = 10;

row["NickName"] = "人物10";

row["QNumber"] = "83223563";

dt.Rows.Add(row);

Cache["Data"] = dt;

}

else

{

dt = Cache["Data"] as DataTable;

}

return dt;

//显然原作者只是为了演示无刷新功能,才自己写数据源(从整个代码来看,可见原作者功底之深厚)

//那么我们就得写自己的获取数据代码

//这个就不用我写了吧,只要从数据库获取后以DataTable的形式返回即可。

}

#region 实现ICallbackEventHandler 成员RaiseCallbackEvent#region 实现ICallbackEventHandler 成员RaiseCallbackEvent

//这个就是实现无刷新的回调方法了。

//其实我们所说的无刷新分页,只是看上去不刷新,其运行时数据还是刷新的,要不然怎么让不同的页面显示不同的内容呢?

//它是以回调的机制获取新的数据流然后再将新的数据流重新绘制显示出来

public void RaiseCallbackEvent(string eventArgument)

{

currentPageIndex = Convert.ToInt32(eventArgument);

BindList(currentPageIndex, false);

}

public string GetCallbackResult()

{

//返回再次绑定后的Repeater的表现内容

return RenderControl(List);

}

#endregion

/**/

/// <summary>

/// 获取指定控件重画的内容

/// </summary>

/// <param name="control"></param>

/// <returns></returns>

private string RenderControl(Control control)

{

StringWriter writer1 = new StringWriter(CultureInfo.InvariantCulture);

HtmlTextWriter writer2 = new HtmlTextWriter(writer1);

control.RenderControl(writer2);

writer2.Flush();

writer2.Close();

return writer1.ToString();

}

//显示数据

//显示数据这个一般自己有自己定义的显示数据形式,所以这个可以根据自己需求修改它,你设置可以不要它,自己重新来写

protected void List_ItemDataBound(object sender, RepeaterItemEventArgs e)

{

if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType ==ListItemType.AlternatingItem)

{

Label NickName = e.Item.FindControl("NickName") as Label;

Label QNumber = e.Item.FindControl("QNumber") as Label;

DataRow row = e.Item.DataItem as DataRow;

NickName.Text = row["NickName"].ToString();

QNumber.Text = row["QNumber"].ToString();

}

}

}

}

最近有朋友在问,如果不使用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.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

8 <html xmlns="http://www.w3.org/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#region 实现ICallbackEventHandler 成员RaiseCallbackEvent

163


164

public void RaiseCallbackEvent(string eventArgument)

165





{

166

currentPageIndex = Convert.ToInt32(eventArgument);

167

BindList(currentPageIndex, false);

168

}

169


170

public string GetCallbackResult()

171





{

172

//返回再次绑定后的Repeater的表现内容

173

return RenderControl(List);

174

}

175

#endregion

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参数,内容就是相同的,相当于传到服务器再原封不动的传回来,因此用于回发和接收时共享数据。

  小示例可变换多种实现,希望大家都能找到适合自己简便实现的办法。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: