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常用运算符(Operators)-javascript基础教程
Dec 14 Javascript
非常棒的10款jQuery 幻灯片插件
Jun 14 Javascript
Javascript实现关联数据(Linked Data)查询及注意细节
Feb 22 Javascript
js修改input的type属性问题探讨
Oct 12 Javascript
jQuery实现简单的文件上传进度条效果
Mar 26 Javascript
Jquery AJAX POST与GET之间的区别详细介绍
Oct 17 Javascript
关于 jQuery Easyui异步加载tree的问题解析
Dec 06 Javascript
简单谈谈关于Angular Cli打包的事
Sep 05 Javascript
详解vuex中action何时完成以及如何正确调用dispatch的思考
Jan 21 Javascript
微信小程序自定义波浪组件使用方法详解
Sep 21 Javascript
javascript运行机制之执行顺序理解
Aug 03 Javascript
在vue-cli创建的项目中使用sass操作
Aug 10 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购物车实现代码
2011/10/10 PHP
Symfony2实现从数据库获取数据的方法小结
2016/03/18 PHP
PHP排序二叉树基本功能实现方法示例
2018/05/26 PHP
ThinkPHP like模糊查询,like多匹配查询,between查询,in查询,一般查询书写方法
2018/09/26 PHP
PHP的PDO事务与自动提交
2019/01/24 PHP
修改jQuery.Autocomplete插件 支持中文输入法 避免TAB、ENTER键失效、导致表单提交
2009/10/11 Javascript
js中的cookie的读写操作示例详解
2014/04/17 Javascript
js通过location.search来获取页面传来的参数
2014/09/11 Javascript
MVVM模式中ViewModel和View、Model有什么区别?
2015/06/19 Javascript
JS+CSS实现简易实用的滑动门菜单效果
2015/09/18 Javascript
15个常用的jquery代码片段
2015/12/19 Javascript
Angular和百度地图的结合实例代码
2016/10/19 Javascript
js 中获取制定的cook信息实现方法
2016/11/19 Javascript
Jquery Easyui表单组件Form使用详解(30)
2016/12/19 Javascript
原生JS实现几个常用DOM操作API实例
2017/01/19 Javascript
jQuery实现的粘性滚动导航栏效果实例【附源码下载】
2017/10/19 jQuery
浅谈Emergence.js 检测元素可见性的 js 插件
2017/11/18 Javascript
Vue项目中如何引入icon图标
2018/03/28 Javascript
Vue ElementUI实现:限制输入框只能输入正整数的问题
2020/07/31 Javascript
Python 详解基本语法_函数_返回值
2017/01/22 Python
pandas使用apply多列生成一列数据的实例
2018/11/28 Python
对python3 中方法各种参数和返回值详解
2018/12/15 Python
python binascii 进制转换实例
2019/06/12 Python
python按行读取文件并找出其中指定字符串
2019/08/08 Python
python sorted方法和列表使用解析
2019/11/18 Python
使用PyTorch训练一个图像分类器实例
2020/01/08 Python
基于Python共轭梯度法与最速下降法之间的对比
2020/04/02 Python
Python操作Jira库常用方法解析
2020/04/10 Python
python高级特性简介
2020/08/13 Python
微软中国官方商城:Microsoft Store中国
2018/10/12 全球购物
总裁助理岗位职责
2014/02/17 职场文书
绩效管理实施方案
2014/03/19 职场文书
私人会所最新创业计划书范文
2014/03/24 职场文书
2015年办公室工作总结范文
2015/03/31 职场文书
2015年小学财务工作总结
2015/07/20 职场文书
2016暑期社会实践新闻稿
2015/11/25 职场文书