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


Posted in Javascript onJanuary 22, 2010

如果你所在公司的开发环境或者项目的开发环境处于单一语言的开发环境之中,框架不适用,因为框架的使用范围之一就是针对一个项目中存在多个语言开发的业务模块,而新项目都需要这些模块的功能,按照以前的习惯,肯定是重新开发,至少也是将其他的语言开发的业务功能变成webservice接口供新代码调用,在这种情况下,本文讨论的框架就可以派上用场并且还能在客户端消除语言差异,只使用纯javascript和html静态代码进行开发。

当然即使在单一的语言环境下,仍然可以使用该模型进行开发,不过开发人员就无法享受到各种优秀的服务端控件(Asp.net控件,专门为java开发的控件等等),只能使用纯javascript控件,这会对开发人员造成不方便(特别是依赖服务端控件的开发人员尤其如此)。

经过以上两篇博文的谈论,我们发现这种模型是完全有用武之地的,它将服务端的语言彻底和客户端分离,开发客户端的人员(在理论条件下)可以完全忽略服务端的语言种类,只进行纯Javascript开发,利用JQUERY中提供的AJAX方法同服务端方法通信。

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

 

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

 

这个时候可以会首先想到效率的问题:

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

 

先看下面几个推论:

1)WebService接口的效率慢 <---> 异步获取数据 ,两者互相能够抵消吗?

2)客户端采用Post的方式,可以减少数据的量,能部分抵消WebService接口的效率慢吗?

以上两个推论,虽然我们没完全做过对比,但可以肯定的说,它们是有对冲效率的,WebService慢,反映在页面端无怪乎就是页面等待长时间不出来,造成用户体验下降,但因为采用异步获取的方式,这种情况还会出现吗?应该不会。

在传送过程中,采用Post方式,数据量大大减少,又采用了异步方式,实际运行效果应该是相当不错的。

 

但对于某些特殊情况并且有很普遍的问题,比如Table表格的分页情况,我们又该怎么处理呢?

Table表格数据填充和分页 这个在页面上非常普遍的问题确对以上的推论造成了威胁,究其原因就是因为一般的分页代码都是把数据返回到客户端内存中,然后进行分页,因此大量的数据从服务端传递到客户端,必然造成问题,其实这个问题不仅仅是这个框架的问题,所有采用这种方式进行分页的代码都存在这样的问题,只不过这个框架采用WebService接口与客户端通信,才导致这个问题的重要性被无限放大了。

以下我们就来讨论在这种框架下进行分页的处理:

环境:Visual studio 2005

         JQuery 1.3.2

         SQLServer2005

分页原理:

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

 

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

 

代码片段:

服务端填充Table表格代码----:

说明:

TB_WEB_NZ_INVESTMENT  是实体类,对应表对象

FlowID  表对象的字段属性,通过它获取一类相似的数据记录

 

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

/// <summary> 
/// 分页功能的表格填充服务端 
/// </summary> 
/// <param name="FlowID"></param> 
/// <param name="PageCount">每页数目</param> 
/// <param name="CurrentPage">当前页</param> 
/// <returns></returns> 
[WebMethod] 
[ScriptMethod(ResponseFormat = ResponseFormat.Json)] 
public string Load_ContributivePerson_Table(string FlowID, int PageCount, int CurrentPage) 
{ 
List<TB_WEB_NZ_INVESTMENT> list = new List<TB_WEB_NZ_INVESTMENT>(); list = objBusinessFacade.GetTB_WEB_NZ_INVESTMENT_CollectionByFlowID(FlowID); 
int TotalPageCount = 0; 
if (PageCount != 0) 
{ 
if ((list.Count % PageCount) > 0) 
{ 
TotalPageCount = list.Count / PageCount + 1; 
} 
else 
{ 
TotalPageCount = list.Count / PageCount; 
} 
}//if 
if (CurrentPage == 1) 
{ 
//第一页 
if (PageCount < list.Count) 
{ 
list.RemoveRange(PageCount, list.Count - PageCount); 
} 
} 
else if (CurrentPage > 1 && CurrentPage < TotalPageCount) 
{ 
//中间页 
int R1 = (CurrentPage - 1) * PageCount-1; 
int R2 = CurrentPage * PageCount; 
List<TB_WEB_NZ_INVESTMENT> list1 = new List<TB_WEB_NZ_INVESTMENT>(); 
for (int i = 0; i < list.Count; i++) 
{ 
if (i > R1&&i<R2) 
{ 
list1.Add(list[i]); 
} 
} 
list.Clear(); 
list = list1; 
} 
else if (CurrentPage == TotalPageCount) 
{ 
//尾页 
//但返回的显示对象列表确只能是最后一页里面的记录 
//这里需要剔除不是最后一页的元素对象 
list.RemoveRange(0,(CurrentPage-1) * PageCount); 
} 
return new JavaScriptSerializer().Serialize(list); 
}

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

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

结合以上代码和该图讲解:

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页)

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

CurrentPage 等于 2

 int R1 = (CurrentPage - 1) * PageCount-1; 等于4
 int R2 = CurrentPage  * PageCount;             等于10

 

R1 和R2 代表两个区间范围索引,即在索引4(不含索引4) 到 索引10(不含索引10) 之间的元素,是我们要取出的元素

List<TB_WEB_NZ_INVESTMENT> list1 = new List<TB_WEB_NZ_INVESTMENT>(); 
for (int i = 0; i < list.Count; i++) 
{ 
if (i > R1&&i<R2) 
{ 
list1.Add(list[i]); 
} 
} 
list.Clear(); 
list = list1;

3)尾页操作:
//尾页
//但返回的显示对象列表确只能是最后一页里面的记录
//这里需要剔除不是最后一页的元素对象
list.RemoveRange(0,(CurrentPage-1) * PageCount);
尾页的代码就简单一些。
从以上的服务端代码,我们看出虽然每次从数据库返回全部的代码到webservice端,但通过这个方法,就将其无用的记录全部过滤了,把剩下的元素传递到客服端,这样不管记录有多少条,每次返回页面的都只有一点点,提高了效率,避免了webservice传递大数据的问题,这样这个框架在传递大数据的方面基本不存在任何问题(排除一些及其特殊的东西),运用这个框架在效率方面不存在任何问题,甚至比普通的页面还要快。
客户端代码片段:
客户端就不再详细说明了,客户端需要传入
PageCount

每页显示的记录数
CurrentPage 当前页数
表格的html:
代码

<table id="TData" width="100%" > 
<thead id="thead"> 
<tr id="TR_Header" class="MyTableTR_Header" align="center" style=" height:25px"> 
<td style="width:1%; display:none" class="MyTableTD"></td> 
<td style="width:10%" >投资人类型</td> 
<td style="width:10%">投资人</td> 
<td style="width:10%">出资方式</td> 
<td style="width:10%">认缴出资额</td> 
<td style="width:10%">实缴出资额</td> 
<td style="width:10%">出资比例</td> 
<td style="width:15%">余额缴付期限</td> 
<td style="width:15%">资料是否完整</td> 
<td style="width:10%">操作</td> 
</tr> 
</thead> 
<tbody id="tbody_Data"></tbody> 
<tfoot id="tfoot_foot"> 
<tr align="right"> 
<td style="width:100%" colspan="9"> 
<a href="#" id="First_A">首页</a> 
<a href="#" id="Prev_A">上一页</a> 
<a href="#" id="Next_A">下一页</a> 
<a href="#" id="Last_A">尾页</a> 
跳到<input id="ToPageNo" type="text" style="width:20px; height:10px; font-size:9px"/>页 | 
总页数:<span id="showTotalPage" style="color:Red"></span>页 
</td> 
</tr> 
</tfoot> 
</table>

填充数据的js函数:
代码
//引导数据填充表格(Table) 
function Load_TableData(FlowID,CurrentPage) 
{ 
$.ajax({ 
type: "POST", 
url: IPServer +"JsonService.asmx/Load_ContributivePerson_Table", 
data:"{FlowID:'"+FlowID+"',PageCount:"+PageCount+",CurrentPage:" + CurrentPage +"}" , 
contentType: "application/json; charset=utf-8", 
dataType: "json", 
success: function(msg){ 
msg = msg.replace(new RegExp('(^|[^\\\\])\\"\\\\/Date\\((-?[0-9]+)\\)\\\\/\\"', 'g'), "$1new Date($2)"); 
var data = eval("(" + msg + ")"); 
var strTR=""; 
var RowCount = 1; 
jQuery.each(data, function(rec) { 
strTR += "<TR id='TR_" + RowCount + "' class='MyTableTR' align='center' >"; 
strTR += " <TD style='width:1%; display:none' id='Key_"+RowCount+"' class='MyTableTD' >" + this.INVID + "</TD>"; 
strTR += " <TD style='width:10%' class='MyTableTD' >" + this.INVTYPEName + "</TD>"; 
strTR += " <TD style='width:10%' class='MyTableTD' >" + this.INV + "</TD>"; 
strTR += " <TD style='width:10%' class='MyTableTD' >" + this.CONFORM + "</TD>"; 
strTR += " <TD style='width:10%' class='MyTableTD' >" + this.SUBCONAM + "</TD>"; 
strTR += " <TD style='width:10%' class='MyTableTD' >" + this.ACCONAM + "</TD>"; 
strTR += " <TD style='width:10%' class='MyTableTD' >" + this.CONPROP + "</TD>"; 
strTR += " <TD style='width:15%' class='MyTableTD' >" + this.BALDEPER_ShortString + "</TD>"; 
strTR += " <TD style='width:15%' class='MyTableTD' >" + this.IsDataCompleteness + "</TD>"; 
strTR += " <TD style='width:10%' class='MyTableTD' ><a id='Link_"+RowCount+"' href='#' >选择</a></TD>"; 
strTR += "</TR>"; 
RowCount++; 
});//jQuery.each 
$("#tbody_Data").empty(); 
$("#tbody_Data").append(strTR); 
$("#CurrentPage").html(CurrentPage); 
}, 
error:function(msg){ 
alert( "Error: " + msg ); 
} 
}); 
}//function Load_TableData()

首页,上一页,下一页,尾页的操作:
说明:
$("#CurrentPage").html()

存储当前页
(调用代码在上个函数红色处) 
$("#TotalPageCount").html()

存储总页数
(调用代码有个专门的函数,见下面)

代码
$("#First_A").click(function(){//首页 链接操作 
Load_TableData(strFlowID,1); 
}); 
$("#Prev_A").click(function(){//上一页 链接操作 
var intCurrentPage = Number(c); 
if(intCurrentPage>1) 
{ 
Load_TableData(strFlowID,intCurrentPage-1); 
} 
}); 
$("#Next_A").click(function(){//下一页 链接操作 
var intCurrentPage = Number($("#CurrentPage").html()); 
var intTotalPageCount = Number($("#TotalPageCount").html()); 
if(intCurrentPage<intTotalPageCount) 
{ 
Load_TableData(strFlowID,intCurrentPage+1); 
} 
}); 
$("#Last_A").click(function(){//尾页 链接操作 
intLastPage = Number($("#TotalPageCount").html()); 
Load_TableData(strFlowID,intLastPage); 
});

返回总页数的客户端函数:
代码
//返回页数 
function Get_TableData_TotalCount(FlowID) 
{ 
$.ajax({ 
type: "POST", 
url: IPServer +"JsonService.asmx/Get_ContributivePersonTable_TotalPageCount", 
data:"{FlowID:'"+FlowID +"',PageCount:"+PageCount+"}" , 
contentType: "application/json; charset=utf-8", 
dataType: "json", 
success: function(msg){ 
var data = eval("(" + msg + ")"); 
jQuery.each(data, function(rec) { 
$("#TotalPageCount").html(this.Info); 
$("#showTotalPage").html(this.Info); 
});//jQuery.each 
}, 
error:function(msg){ 
alert( "Error: " + msg ); 
} 
}); 
} 
<div id="CurrentPage" ></div> 
<div id="TotalPageCount" ></div>

最后效果图:

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

总结:

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

框架的应用探索正在稳步进行中。。。。。。

Javascript 相关文章推荐
js原生appendChild的bug解决心得分享
Jul 01 Javascript
Jquery的hide及toggle方法让超链接慢慢消失
Sep 06 Javascript
javascript日期格式化方法小结
Dec 17 Javascript
jQuery给指定的table动态添加删除行的操作方法
Oct 12 Javascript
JS前向后瞻正则表达式定义与用法示例
Dec 27 Javascript
微信小程序页面滑动屏幕加载数据效果
Nov 16 Javascript
详解webpack4升级指南以及从webpack3.x迁移
Jun 12 Javascript
Vue使用mixin分发组件的可复用功能
Sep 01 Javascript
vue双向绑定数据限制长度的方法
Nov 04 Javascript
最全vue的vue-amap使用高德地图插件画多边形范围的示例代码
Jul 17 Javascript
javascript递归函数定义和用法示例分析
Jul 22 Javascript
利用前端HTML+CSS+JS开发简单的TODOLIST功能(记事本)
Apr 13 Javascript
被jQuery折腾得半死,揭秘为何jQuery为何在IE/Firefox下均无法使用
Jan 22 #Javascript
jQuery 入门级学习笔记及源码
Jan 22 #Javascript
JQuery 确定css方框模型(盒模型Box Model)
Jan 22 #Javascript
Jquery实战_读书笔记2 选择器
Jan 22 #Javascript
Jquery实战_读书笔记1—选择jQuery
Jan 22 #Javascript
jquery last-child 列表最后一项的样式
Jan 22 #Javascript
javascript 拖放效果实现代码
Jan 22 #Javascript
You might like
晶体管单管来复再生式收音机
2021/03/02 无线电
ThinkPHP查询中的魔术方法简述
2014/06/25 PHP
使用URL传输SESSION信息
2015/07/14 PHP
PHP中常用的数组操作方法笔记整理
2016/05/16 PHP
PHP编程实现多维数组按照某个键值排序的方法小结【2种方法】
2017/04/27 PHP
php session_decode函数用法讲解
2019/05/26 PHP
写的htc的数据表格
2007/01/20 Javascript
给Function做的OOP扩展
2009/05/07 Javascript
深入剖析JavaScript编程中的对象概念
2015/10/21 Javascript
实例浅析js的this
2016/12/11 Javascript
js实现旋转木马效果
2017/03/17 Javascript
利用node.js爬取指定排名网站的JS引用库详解
2017/07/25 Javascript
JS中的事件委托实例浅析
2018/03/22 Javascript
利用Angular2的Observables实现交互控制的方法
2018/12/27 Javascript
ES6 Class中实现私有属性的一些方法总结
2019/07/08 Javascript
vue+Element中table表格实现可编辑(select下拉框)
2020/05/21 Javascript
跟老齐学Python之玩转字符串(2)
2014/09/14 Python
Python查找第n个子串的技巧分享
2018/06/27 Python
新年快乐! python实现绚烂的烟花绽放效果
2019/01/30 Python
python学习--使用QQ邮箱发送邮件代码实例
2019/04/16 Python
使用Python轻松完成垃圾分类(基于图像识别)
2019/07/09 Python
应用OpenCV和Python进行SIFT算法的实现详解
2019/08/21 Python
python内置函数sorted()用法深入分析
2019/10/08 Python
快速查找Python安装路径方法
2020/02/06 Python
Pycharm中import torch报错的快速解决方法
2020/03/05 Python
用python 绘制茎叶图和复合饼图
2021/02/26 Python
使用CSS实现阅读进度条
2017/02/27 HTML / CSS
CSS3自定义滚动条样式的示例代码
2017/08/21 HTML / CSS
可打印的优惠券、杂货和优惠券代码:Coupons.com
2018/06/12 全球购物
Clos19英国:高档香槟、葡萄酒和烈酒在线购物平台
2020/07/10 全球购物
毕业生文员求职信
2013/11/03 职场文书
自荐信范文
2013/12/10 职场文书
出生医学证明样本
2014/01/17 职场文书
计算机专业自荐信
2014/05/24 职场文书
安全标兵事迹材料
2014/08/17 职场文书
记者节感言
2015/08/03 职场文书