热门:网页模板.net视频教程JQueryMVCjsonExtJs源码示例三级联动JQuery菜单
您现在的位置:.Net中文社区>> AJAX编程>>正文内容

JQuery构建客户/服务分离的链接模型中Table分页代码效率初探!

发布时间:2010年01月20日点击数:

开发客户端的人员(在理论条件下)可以完全忽略服务端的语言种类,只进行纯Javascript开发,利用JQUERY中提供的AJAX方法同服务端方法通信。

从上面的整体架构图,我们看出:其客户端都是WebService接口来获取数据和传送数据的,而服务端业务模型是什么语言开发的,完全不需要关注(当然在现实情况下,一般WebService接口最好同服务端业务模型是一个语言开发的)。

这个时候可以会首先想到效率的问题:
众所周知,WebService接口的效率较慢,那么这样搞是不是会让采用这种结构模型开发的网站速度变慢,与其这样,还不如采用常规的方法开发,不仅熟悉而且速度也不错呢?

先看下面几个推论:
1)WebService接口的效率慢 <---> 异步获取数据 ,两者互相能够抵消吗?
2)客户端采用Post的方式,可以减少数据的量,能部分抵消WebService接口的效率慢吗?
以上两个推论,虽然我们没完全做过对比,但可以肯定的说,它们是有对冲效率的,WebService慢,反映在页面端无怪乎就是页面等待长时间不出来,造成用户体验下降,但因为采用异步获取的方式,这种情况还会出现吗?应该不会。
在传送过程中,采用Post方式,数据量大大减少,又采用了异步方式,实际运行效果应该是相当不错的。

但对于某些特殊情况并且有很普遍的问题,比如Table表格的分页情况,我们又该怎么处理呢?
Table表格数据填充和分页 这个在页面上非常普遍的问题确对以上的推论造成了威胁,究其原因就是因为一般的分页代码都是把数据返回到客户端内存中,然后进行分页,因此大量的数据从服务端传递到客户端,必然造成问题,其实这个问题不仅仅是这个框架的问题,所有采用这种方式进行分页的代码都存在这样的问题,只不过这个框架采用WebService接口与客户端通信,才导致这个问题的重要性被无限放大了。
以下我们就来讨论在这种框架下进行分页的处理:
环境:Visual studio 2005
JQuery 1.3.2
SQLServer2005
分页原理:

 

从上图中,看到不管数据表中有多少数据,每次返回到客户端的数据都是一页的数据,这种方法没有采用存储过程方式,而是在webservice端进行处理的。

代码片段:
服务端填充Table表格代码----:
说明:
TB_WEB_NZ_INVESTMENT 是实体类,对应表对象
FlowID 表对象的字段属性,通过它获取一类相似的数据记录

代码中有对【首页】,【尾页】,【中间页】的元素进行过滤,对返回的泛型List对象进行范围过滤

  1. /// <summary> 
  2.     /// 分页功能的表格填充服务端 
  3.     /// </summary> 
  4.     /// <param name="FlowID"></param> 
  5.     /// <param name="PageCount">每页数目</param> 
  6.     /// <param name="CurrentPage">当前页</param> 
  7.     /// <returns></returns> 
  8.     [WebMethod] 
  9.     [ScriptMethod(ResponseFormat = ResponseFormat.Json)] 
  10.     public string Load_ContributivePerson_Table(string FlowID, int PageCount, int CurrentPage) 
  11.     { 
  12.         List<TB_WEB_NZ_INVESTMENT> list = new List<TB_WEB_NZ_INVESTMENT>(); 
  13.         
  14.  
  15.         list = objBusinessFacade.GetTB_WEB_NZ_INVESTMENT_CollectionByFlowID(FlowID); 
  16.  
  17.         int TotalPageCount = 0; 
  18.         if (PageCount != 0) 
  19.         { 
  20.             if ((list.Count % PageCount) > 0) 
  21.             { 
  22.                 TotalPageCount = list.Count / PageCount + 1; 
  23.             } 
  24.             else 
  25.             { 
  26.                 TotalPageCount = list.Count / PageCount; 
  27.             } 
  28.  
  29.         }//if 
  30.  
  31.  
  32.         if (CurrentPage == 1) 
  33.         { 
  34.             //第一页 
  35.             if (PageCount < list.Count) 
  36.             { 
  37.                 list.RemoveRange(PageCount, list.Count - PageCount); 
  38.             } 
  39.  
  40.             
  41.  
  42.         } 
  43.         else if (CurrentPage > 1 && CurrentPage < TotalPageCount) 
  44.         { 
  45.             //中间页 
  46.              
  47.              
  48.             int R1 = (CurrentPage - 1) * PageCount-1; 
  49.             int R2 = CurrentPage  * PageCount; 
  50.             
  51.             List<TB_WEB_NZ_INVESTMENT> list1 = new List<TB_WEB_NZ_INVESTMENT>(); 
  52.             for (int i = 0; i < list.Count; i++) 
  53.             { 
  54.                 if (i > R1&&i<R2) 
  55.                 { 
  56.                     list1.Add(list[i]); 
  57.                 } 
  58.             } 
  59.             list.Clear(); 
  60.             list = list1; 
  61.         } 
  62.         else if (CurrentPage == TotalPageCount) 
  63.         { 
  64.             //尾页 
  65.             
  66.             //但返回的显示对象列表确只能是最后一页里面的记录 
  67.             //这里需要剔除不是最后一页的元素对象 
  68.  
  69.             list.RemoveRange(0,(CurrentPage-1) * PageCount); 
  70.         } 
  71.  
  72.  
  73.         return new JavaScriptSerializer().Serialize(list); 
  74.     } 

原理说明图:-----------------------

结合以上代码和该图讲解:
1)首页操作:
list.RemoveRange(PageCount, list.Count - PageCount); 
翻译成数字:list.RemoveRange(5,14-5);
首页显示的元素:A1 A2 A3 A4 A5 对应的索引:0 1 2 3 4
list.RemoveRange(5,14-5); //排除索引值为5(含自身)的后面的所有元素,这样列表中只有A1-A5 元素

2)中间页操作:(这里就是第2页)

  1. List<TB_WEB_NZ_INVESTMENT> list1 = new List<TB_WEB_NZ_INVESTMENT>(); 
  2. for (int i = 0; i < list.Count; i++) 
  3.       if (i > R1&&i<R2) 
  4.       { 
  5.            list1.Add(list[i]); 
  6.       } 
  7. list.Clear(); 
  8. list = list1; 

3)尾页操作:

  1.  //尾页 
  2.             
  3. //但返回的显示对象列表确只能是最后一页里面的记录 
  4. //这里需要剔除不是最后一页的元素对象 
  5.  
  6. list.RemoveRange(0,(CurrentPage-1) * PageCount); 

尾页的代码就简单一些。

从以上的服务端代码,我们看出虽然每次从数据库返回全部的代码到webservice端,但通过这个方法,就将其无用的记录全部过滤了,把剩下的元素传递到客服端,这样不管记录有多少条,每次返回页面的都只有一点点,提高了效率,避免了webservice传递大数据的问题,这样这个框架在传递大数据的方面基本不存在任何问题(排除一些及其特殊的东西),运用这个框架在效率方面不存在任何问题,甚至比普通的页面还要快。

客户端代码片段:
客户端就不再详细说明了,客户端需要传入
PageCount  每页显示的记录数
CurrentPage 当前页数

表格的html:

  1. <table id="TData" width="100%" > 
  2.      <thead id="thead"> 
  3.          <tr id="TR_Header" class="MyTableTR_Header" align="center" style=" height:25px"> 
  4.                <td  style="width:1%; display:none"  class="MyTableTD"></td> 
  5.                <td  style="width:10%" >投资人类型</td> 
  6.                <td  style="width:10%">投资人</td> 
  7.                <td  style="width:10%">出资方式</td> 
  8.                <td  style="width:10%">认缴出资额</td> 
  9.                <td  style="width:10%">实缴出资额</td> 
  10.                <td  style="width:10%">出资比例</td> 
  11.                <td  style="width:15%">余额缴付期限</td> 
  12.                <td  style="width:15%">资料是否完整</td> 
  13.                <td  style="width:10%">操作</td> 
  14.          </tr> 
  15.       </thead> 
  16.       <tbody id="tbody_Data"></tbody> 
  17.       <tfoot id="tfoot_foot">  
  18.          <tr align="right"> 
  19.                <td style="width:100%" colspan="9"> 
  20.                                      
  21.                    <a href="#" id="First_A">首页</a> 
  22.                    <a href="#" id="Prev_A">上一页</a> 
  23.                    <a href="#" id="Next_A">下一页</a> 
  24.                    <a href="#" id="Last_A">尾页</a> 
  25.                    跳到<input id="ToPageNo" type="text"  style="width:20px; height:10px; font-size:9px"/>页 |  
  26.                    总页数:<span id="showTotalPage" style="color:Red"></span>页 
  27.                   </td> 
  28.                                  
  29.          </tr> 
  30.       </tfoot> 
  31. </table> 

填充数据的js函数:

  1. //引导数据填充表格(Table) 
  2.     function Load_TableData(FlowID,CurrentPage) 
  3.     { 
  4.          
  5.         $.ajax({ 
  6.             type: "POST"
  7.             url: IPServer +"JsonService.asmx/Load_ContributivePerson_Table"
  8.             data:"{FlowID:'"+FlowID+"',PageCount:"+PageCount+",CurrentPage:" + CurrentPage +"}" , 
  9.             contentType: "application/json; charset=utf-8"
  10.             dataType: "json"
  11.             success: function(msg){ 
  12.                  msg = msg.replace(new RegExp('(^|[^\\\\])\\"\\\\/Date\\((-?[0-9]+)\\)\\\\/\\"''g'), "$1new Date($2)"); 
  13.                  var data = eval("(" + msg + ")");   
  14.                  var strTR=""
  15.                  var RowCount = 1; 
  16.                  jQuery.each(data, function(rec) {   
  17.                         
  18.                         
  19.                        strTR += "<TR id='TR_" + RowCount + "' class='MyTableTR' align='center' >"
  20.                        strTR += "   <TD style='width:1%; display:none' id='Key_"+RowCount+"' class='MyTableTD' >" + this.INVID + "</TD>"
  21.                        strTR += "   <TD style='width:10%' class='MyTableTD' >" + this.INVTYPEName + "</TD>"
  22.                        strTR += "   <TD style='width:10%' class='MyTableTD' >" + this.INV + "</TD>"
  23.                        strTR += "   <TD style='width:10%' class='MyTableTD' >" + this.CONFORM + "</TD>"
  24.                        strTR += "   <TD style='width:10%' class='MyTableTD' >" + this.SUBCONAM + "</TD>"
  25.                        strTR += "   <TD style='width:10%' class='MyTableTD' >" + this.ACCONAM + "</TD>"
  26.                        strTR += "   <TD style='width:10%' class='MyTableTD' >" + this.CONPROP + "</TD>"
  27.                        strTR += "   <TD style='width:15%' class='MyTableTD' >" + this.BALDEPER_ShortString + "</TD>"
  28.                        strTR += "   <TD style='width:15%' class='MyTableTD' >" + this.IsDataCompleteness + "</TD>"
  29.                        strTR += "   <TD style='width:10%' class='MyTableTD' ><a id='Link_"+RowCount+"' href='#' >选择</a></TD>"
  30.                        strTR += "</TR>"
  31.                         
  32.                         
  33.                                                            
  34.                        RowCount++; 
  35.                        
  36.                  });//jQuery.each  
  37.                  $("#tbody_Data").empty(); 
  38.                  $("#tbody_Data").append(strTR);                 
  39.                  $("#CurrentPage").html(CurrentPage); 
  40.                           }, 
  41.             error:function(msg){ 
  42.                  alert( "Error: " + msg ); 
  43.             } 
  44.  
  45.         }); 
  46.     }//function Load_TableData()   

首页,上一页,下一页,尾页的操作:
说明:
$("#CurrentPage").html()      存储当前页  (调用代码在上个函数红色处)
$("#TotalPageCount").html()    存储总页数  (调用代码有个专门的函数,见下面)

  1. $("#First_A").click(function(){//首页 链接操作 
  2.              
  3.      Load_TableData(strFlowID,1); 
  4.              
  5. }); 
  6.          
  7. $("#Prev_A").click(function(){//上一页 链接操作 
  8.      var intCurrentPage =  Number(c); 
  9.              
  10.      if(intCurrentPage>1) 
  11.      { 
  12.         Load_TableData(strFlowID,intCurrentPage-1); 
  13.      } 
  14. }); 
  15.          
  16. $("#Next_A").click(function(){//下一页 链接操作 
  17.      var intCurrentPage =  Number($("#CurrentPage").html()); 
  18.     var intTotalPageCount = Number($("#TotalPageCount").html()); 
  19.              
  20.     if(intCurrentPage<intTotalPageCount) 
  21.     { 
  22.         Load_TableData(strFlowID,intCurrentPage+1); 
  23.     } 
  24.              
  25. }); 
  26.          
  27. $("#Last_A").click(function(){//尾页 链接操作 
  28.      intLastPage = Number($("#TotalPageCount").html()); 
  29.              
  30.     Load_TableData(strFlowID,intLastPage); 
  31. }); 

返回总页数的客户端函数:

  1. //返回页数 
  2.     function Get_TableData_TotalCount(FlowID) 
  3.     { 
  4.          $.ajax({ 
  5.             type: "POST"
  6.             url: IPServer +"JsonService.asmx/Get_ContributivePersonTable_TotalPageCount"
  7.             data:"{FlowID:'"+FlowID +"',PageCount:"+PageCount+"}" , 
  8.             contentType: "application/json; charset=utf-8"
  9.             dataType: "json"
  10.             success: function(msg){ 
  11.                   
  12.                  var data = eval("(" + msg + ")");   
  13.                   
  14.                  jQuery.each(data, function(rec) {   
  15.                     $("#TotalPageCount").html(this.Info);  
  16.                     $("#showTotalPage").html(this.Info); 
  17.                  });//jQuery.each  
  18.                  
  19.  
  20.             }, 
  21.             error:function(msg){ 
  22.                  alert( "Error: " + msg ); 
  23.             } 
  24.  
  25.         }); 
  26.     } 
  27.  
  28. <div id="CurrentPage" ></div> 
  29. <div id="TotalPageCount" ></div> 

最后效果图:

总结:
Table数据填充并分页还有很多方法,这里只是提供了一种通过服务端就进行过滤的方法,让其返回客户端的数据始终就一点,提高了效率。

更多模板/案例展示

亚太盛典国际婚纱摄影 本案例由亚太盛典国际婚纱公司所部署,精美的界面,合理的布局是网站的一大特色!
亚太盛典国际婚纱摄影 本案例由亚太盛典国际婚纱公司所部署,精美的界面,合理的布局是网站的一大特色!
关于我们 | 联系我们 | 团队日志 | 网站地图 | 网站合作