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

  http://www.cnblogs.com/shouzheng/archive/2008/04/17/1158281.html
Repeater无刷新分页
2011-01-28 19:14

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

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

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

代码地址:http://www.cnblogs.com/shouzheng/archive/2008/04/17/1158281.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>&nbsp;&nbsp;",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(1true);
 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
 31callbackScript, 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>&nbsp;&nbsp;"
 74
 75pageIndex);
 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
181ListItemType.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参数,内容就是相同的,相当于传到服务器再原封不动的传回来,因此用于回发和接收时共享数据。
  小示例可变换多种实现,希望大家都能找到适合自己简便实现的办法。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值