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 相关文章推荐
JavaScript解析URL参数示例代码
Aug 12 Javascript
javascript生成json数据简单示例分享
Feb 14 Javascript
jquery如何扑捉回车键触发的事件
Apr 24 Javascript
Javascript removeChild()删除节点及删除子节点的方法
Dec 27 Javascript
Jquery获取第一个子元素简单实例
Jun 02 Javascript
JavaScript 中有关数组对象的方法(详解)
Aug 15 Javascript
利用Node.js+Koa框架实现前后端交互的方法
Feb 27 Javascript
Vue shopCart 组件开发详解
Jan 26 Javascript
JavaScript实现微信号随机切换代码
Mar 09 Javascript
详解javascript appendChild()的完整功能
Aug 18 Javascript
react基本安装与测试示例
Apr 27 Javascript
swiper实现导航滚动效果
Dec 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
PHP IF ELSE简化/三元一次式的使用
2011/08/22 PHP
php实现利用phpexcel导出数据
2013/08/24 PHP
使用Discuz关键词服务器实现PHP中文分词
2014/03/11 PHP
php使用mkdir创建多级目录入门例子
2014/05/10 PHP
PHP获取本周所有日期或者最近七天所有日期的方法
2018/06/20 PHP
Laravel等框架模型关联的可用性浅析
2019/12/15 PHP
Cookie跨域问题解决方案代码示例
2020/11/24 PHP
举例详解JavaScript中Promise的使用
2015/06/24 Javascript
javascript新闻跑马灯实例代码
2020/07/29 Javascript
JS获取中文拼音首字母并通过拼音首字母快速查找页面内对应中文内容的方法【附demo源码】
2016/08/19 Javascript
基于webpack 实用配置方法总结
2017/09/28 Javascript
详解React 在服务端渲染的实现
2017/11/16 Javascript
Angular使用cli生成自定义文件、组件的方法
2018/09/04 Javascript
vue router导航守卫(router.beforeEach())的使用详解
2019/04/19 Javascript
vue组件化中slot的基本使用方法
2019/05/01 Javascript
Layui数据表格 前后端json数据接收的方法
2019/09/19 Javascript
详解Angular Karma测试的持续集成实践
2019/11/15 Javascript
微信小程序背景音乐开发详解
2019/12/12 Javascript
Node.js API详解之 zlib模块用法分析
2020/05/19 Javascript
0基础学习前端开发的一些建议
2020/07/14 Javascript
Python简单实现子网掩码转换的方法
2016/04/13 Python
python中列表和元组的区别
2017/12/18 Python
Python编程二分法实现冒泡算法+快速排序代码示例
2018/01/15 Python
在Python中pandas.DataFrame重置索引名称的实例
2018/11/06 Python
Python 类属性与实例属性,类对象与实例对象用法分析
2019/09/20 Python
Django-xadmin+rule对象级权限的实现方式
2020/03/30 Python
Python爬取酷狗MP3音频的步骤
2021/02/26 Python
CSS3 media queries + jQuery实现响应式导航
2016/09/30 HTML / CSS
英国健身超市:Fitness Superstore
2019/06/17 全球购物
解释一下Windows的消息机制
2014/01/30 面试题
在校生自我鉴定
2014/01/23 职场文书
党员自我剖析材料范文
2014/10/06 职场文书
2016年暑期教师培训心得体会
2016/01/09 职场文书
《平移和旋转》教学反思
2016/02/19 职场文书
导游词之河北野三坡
2019/12/11 职场文书
联想win10摄像头打不开怎么办?win10笔记本摄像头打不开解决办法
2022/04/08 数码科技