这篇文章只谈jQuery easyui datagrid 的数据加载,因为这也是大家谈论最多的内容。其实easyui datagrid加载数据只有两种方式:一种是ajax加载目标url返回的json数据;另一种是加载js对象,也就是使用loadDate方法。
这里就自己的使用经验,对两种方式做简单总结和归纳,并且对使用过程中容易产生的误区做较为详细的描述,希望能对大家有所帮助。
url方式加载数据
调用方式
目前可能大多数人都是选择这种方式,因为跟流行的框架结合的也比较好,使用url的话,可以将url写在DOM里面或者申明datagrid对象的url属性,以下两种方式都是可以的:
- <table id="tt" style="width:700px;height:auto" title="DataGrid" idField="itemid" url="datagrid_data2.json">
- $('#test').datagrid({
- url:'datagrid_data2.json'
- });
相关方法
load | param | 加载第一页数据,param将代替默认查询参数,注意的是该方法只适用于url方式. |
reload | param | 刷新当前页数据,与load方法不同的时候reload方法刷新当前页数据,而load方法会跳到第一页然后刷新. |
options | null | 获取datagrid实例的各项参数值,常用的参数有url,pageNumber,pageSize这三个参数在请求数据以及分页功能中起重要作用. |
二次加载问题
对于使用url方式的初学者,经常碰到重复请求的问题,这个问题的根源是多次渲染组件,如何避免二次加载这样问题呢,个人觉得注意以下两点基本就可以防止二次加载了。
- 使用load和reload函数去动态加载数据,而不是选择再次渲染组件。很多人再次渲染组件的目的仅仅是为了设置url,这得不偿失,url的设置可以通过options方法获取到组件实例的opts,然后在给opts.url重新赋值即可;
- class方式注册组件和javascript注册方式不要同时使用。class注册方式一般是为了初始化属性,javascript方式则属性和事件都可初始化,但是不管是class方式还是javascipt方式注册组件,每次注册,只要被设置过url属性就会做请求。所以在不可避免要使用javascript方式注册的情况下,索性就不要使用class方式注册了。
因为url方式网上的资料特别多,我这里就简述这么多,下面重点讨论一下loadDate方式加载数据。
加载本地数据方式
首先要明白“加载本地数据”是个什么概念,这里指的是加载javascript对象数据,而javascript数据对象显然可以使是通过其它异步方式获得的,所以这个“加载本地数据”的描述并不准确。
调用方式
先要将url属性设置为null,或者不设置,然后使用datagrid的loadDate方法加载js数据对象,这个对象包含两个属性,一个是记录总数,一个是当前页码的对象数组。例如:
- var obj = {'total':100,'rows':[{id:'1',name:'一'},{id:'2',name:'二'}]};
- $('#tt').datagrid('loadData',obj);
如何分页
不对源码做任何改动的话,可以首先获取datagrid的Pagination对象,然后通过写Pagination对象的onSelectPage事件来实现分页:
- //初始化dategrid
- $('#tt').datagrid({
- url:null,
- pagination:true,
- pageSize:20,
- pageNumber:1,
- rownumbers:true
- });
- $('#tt').datagrid('getPager').pagination({
- displayMsg:'当前显示从 [{from}] 到 [{to}] 共[{total}]条记录',
- onSelectPage : function(pPageIndex, pPageSize) {
- //改变opts.pageNumber和opts.pageSize的参数值,用于下次查询传给数据层查询指定页码的数据
- var gridOpts = $('#tt').datagrid('options');
- gridOpts.pageNumber = pPageIndex;
- gridOpts.pageSize = pPageSize;
- //定义查询条件
- var queryCondition = {name:"世纪之光"};
- //异步获取数据到javascript对象,入参为查询条件和页码信息
- var oData = getAjaxDate("orderManageBuz","qryWorkOrderPaged",queryCondition,gridOpts);
- //使用loadDate方法加载Dao层返回的数据
- $('#tt').datagrid('loadData',{"total" : oData.page.recordCount,"rows" : oData.data});
- }
- });
上面的代码应该很容易看懂了,做出来的分页基本也算正常,唯一的缺憾就是写起来不怎么便捷。那么如何才能便捷地实现分页呢?
之前我写过jQuery easyui datagrid 非URL后台分页的文章,稍微对easyui datagrid做下扩展,增加一个doPagination事件,那么编码就较为简单了。
- //初始化dategrid
- $('#tt').datagrid({
- url:null,
- pagination:true,
- pageSize:20,
- pageNumber:1,
- rownumbers:true,
- doPagination:function(pPageIndex, pPageSize) {
- var gridOpts = $('#tt').datagrid('options');
- //定义查询条件
- var queryCondition = {name:"世纪之光"};
- //异步获取数据到javascript对象,入参为查询条件和页码信息
- var oData = getAjaxDate("orderManageBuz","qryWorkOrderPaged",queryCondition,{pageNumber:gridOpts.pageNumber,pageSize:gridOpts.pageSize});
- //使用loadDate方法加载Dao层返回的数据
- $('#tt').datagrid('loadData',{"total" : oData.page.recordCount,"rows" : oData.data});
- },
- });
这种方式就不用再去获取Pagination对象了,而且也不用设置opts的pageNumber和pageSize这两个属性了,编码变得简易了,是不是变得清爽了很多呢?
加载中效果
easyui datagrid只有在使用url方式获取数据的时候才会显示“加载中……”的遮罩效果,使用loadDate方法加载数据的话,其实也可以用上这效果,只不过稍微麻烦些:
- //初始化dategrid
- $('#tt').datagrid({
- url:null,
- pagination:true,
- pageSize:20,
- pageNumber:1,
- rownumbers:true,
- doPagination:function(pPageIndex, pPageSize) {
- //改变opts.pageNumber和opts.pageSize的参数值,用于下次查询传给数据层查询指定页码的数据
- var gridOpts = $('#tt').datagrid('options');
- gridOpts.pageNumber = pPageIndex;
- gridOpts.pageSize = pPageSize;
- Exec_Wait('tt','loadDateGrid()');
- },
- });
- function loadDateGrid(){
- var gridOpts = $('#tt').datagrid('options');
- //定义查询条件
- var queryCondition = {name:"世纪之光"};
- //异步获取数据到javascript对象,入参为查询条件和页码信息
- var oData = getAjaxDate("orderManageBuz","qryWorkOrderPaged",queryCondition,gridOpts);
- //使用loadDate方法加载Dao层返回的数据
- $('#tt').datagrid('loadData',{"total" : oData.page.recordCount,"rows" : oData.data});
- }
- /**
- * 封装一个公用的方法
- * @param {Object} grid table的id
- * @param {Object} func 获取异步数据的方法
- * @param {Object} time 延时执行时间
- */
- function Exec_Wait(grid,func,time){
- var dalayTime = 500;
- __func_=func;
- __selector_ = '#' + grid;
- $(__selector_).datagrid("loading");
- if (time) {
- dalayTime = time;
- }
- gTimeout=window.setTimeout(_Exec_Wait_,dalayTime);
- }
- function _Exec_Wait_(){
- try{eval(__func_);
- }catch(e){
- alert("__func_:" + __func_ + ";_ExecWait_" + e.message);
- }finally{
- window.clearTimeout(gTimeout);
- $(__selector_).datagrid("loaded");
- }
- }
当然了,你也可以利用datagrid的onLoadSuccess事件来实现,反正最终都是调用datagrid的loding和loaded方法完成等待DIV的显示和隐藏的:
- function loadDateGrid(){
- $('#tt').datagrid('loading');//打开等待div
- var queryCondition = {
- name: "世纪之光"
- };
- var oData = getAjaxDate("orderManageBuz", "qryWorkOrderPaged", queryCondition, oPage);
- $('#tt').datagrid('loadData', {
- "total": oData.page.recordCount,
- "rows": oData.data
- });
- }
- $('#tt').datagrid({
- onLoadSuccess: function(){
- //加载完数据关闭等待的div
- $('#tt').datagrid('loaded');
- }
- });
如何不统计总数
有时候数据层的数据量特别大,查询统计总数的话会很耗时,统计总数就显得不怎么合适了,如何不统计总数完全看你后台怎么写了,可以虚拟一个一个总数,这个数字总是比当前页码大1就行了,具体实现就不在本篇文章关注的范围内了。
到这里,loadData方式加载grid数据就已经算是完美了,至少该有的问题均已经解决了,希望大家有更好建议一起交流……
大侠
我想看看(“orderManageBuz”,”qryWorkOrderPaged”,queryCondition,oPage); 这个是如何实现的. 有源码?
谢谢
管理员 世纪之光 : 2012年06月29日11:36:29 -48楼
@bobo
我勒个去,这个你可以用jquery的ajax+servlet来实现,也可以用dwr的ajax实现,反正就是通过ajax调用后台获取数据,这个不是文章的重点,实现方式太多了,我这里只是举个例子,并没有源代码。
如果你关心的是后台如何处理分页信息的,网上后台分页的源码应该也很多,无非就是处理几个参数而已。
var oData = getAjaxDate(“orderManageBuz”, “qryWorkOrderPaged”, queryCondition, oPage); 这块是你封装后的方法吗? 😀
管理员 世纪之光 : 2017年04月09日08:36:21 地下2层
getAjaxDate只是我写的伪代码,代表同步获取后台数据的方法,具体实现,你用jquery的ajax方法,设置其为同步请求就可以了,如果是异步的话,就用回调函数,或者promise
多谢.大侠
管理员 世纪之光 : 2012年06月29日13:45:25 -46楼
@bobo
不必客气,也没帮到你什么忙,很多东西还是要靠你自己去研究。
我感觉你对jquery ui 颇有研究 可以留一个联系方式吗
可以留一个联系方式吗 我感觉很有用
管理员 世纪之光 : 2012年08月11日07:55:54 -43楼
@jquery 爱好者
对jQuery自身的ui研究不多,只是对easyui涉及得要多一点,联系我的话到这个博客上就可以了,或者QQ:158514145
指出一个小错误:
加载本地数据方式:调用方式:$(‘#tt’).datagrid(‘loadDate’,obj);
loadData是也
管理员 世纪之光 : 2012年08月19日10:36:43 -41楼
@Everhythm
十分感谢你的提醒,立马更正过来,像你这样的热心人应该多一点哈。
我用的是url方式加载第一页,然后翻页是加载本地数据的方式,可是这个时候url就是有值的了,当翻页时就不调用doPagination这个方法了,如果在定义datagrid的时候就设置url为null则就没法加载第一页了。怎么解决呢?
还有一个问题是先加载好页面,当我翻到第二页时左下角显示第二页,我查询后,他还是显示第二页,可是此时我想显示第一页,有的时候查询就一页。这个问题不知道你是否遇见?
管理员 世纪之光 : 2012年09月05日12:20:07 -38楼
@@ssss
我晕哦,哪有两种方式混起来用的啊,这样太乱了,强烈建议你统一使用loadData方式或者统一使用url方式,规范使用是很重要的。
@世纪之光
我用了,可是出现11楼的问题,不知道你是否遇见过吗
管理员 世纪之光 : 2012年09月05日12:33:23 -36楼
@@ssss
页码这个问题对于使用url方式和loadData方式都有解决方式,但是前提是你只使用一种方式,不要混用。
使用loadData方式加载数据的话,查询的时候想回到第一页手工设置一下oPage.pageIndex=1就可以了;
使用url方式的话,使用load方法应该就可以解决你的问题。
OK,可以了,我都用loaddata方式了,感谢你!
管理员 世纪之光 : 2012年09月05日17:06:39 -34楼
@@ssss
呵呵,不客气,越来越多的人使用easyui了,以后这方面资料会越来越多的。
顶一下,正好有个项目要用到这方面的东西,等我回去试试
源代码看的眼花,
我有个问题请教楼主,
是这样的,url 加载数据返回的json,里,我想附带一些动态信息,frozenColumns不同页面是不同的ID,我想动态赋值
url:param.action+’?id=’+param.id+’&t=’+Math.random(),
onLoadSuccess:function(data){
_sortName = data.companyId;
-companyName = data.companyId;
},
sortName:_sortName ,
frozenColumns:[[ {field:companyName } ]]
这样,不知道有什么好的解决方法或思路? QQ:6641984,敬请赐教。
管理员 世纪之光 : 2012年09月20日18:20:49 地下1层
@wilkey 不是很能理解你的意思,如果字段都不确定的话,就根据条件动态构建grid,根据你的附加信息确定grid结构。或者你附加信息能枚举出来有哪些字段的话,索性就把所有可能的字段都加到grid里面,然后通过动态隐藏列的方式现实自己想要的效果。
请问,如何动态的加载datagrid的表头,就是动态的生成columns[[]]
表头的问题我自己解决了。
通过loadData加载的数据,分页的参数怎么取,怎么传递啊
管理员 世纪之光 : 2014年01月06日12:20:32 地下4层
前台传递页码和每页记录数给后台,至于键名自己定义即可,后台获取的时候与之对应就行了;
后台返回给前台的时候只要返回总数和加载到的rows就可以了。
请问如何动态改变表头,$(“#datagridId”).datagrid({columns:columns})我每次都会请求两次url,求帮助
$.ajax({….
‘success’: function(data,statusText){
$(‘#grid’).datagrid(‘loadData’,data);
});
按你的说法loadData方法在api里面定义的时候就是加载第一页数据,但是我这样写表格会直接加载所有的数据.怎样才加载第一页比如前pageSize条呢?比如10条,是在后台读取数据的时候就只读取10条,还是就在js里面实现呢?
管理员 世纪之光 : 2012年10月08日09:40:16 地下1层
@eaayui_b-to-b 首先你要将后台返回的数据格式转换为javascript对象(具体可以使用eval或者第三方js工具转换),然后再使用easyui的loadData方式加载这个对象,loadData再加载的时候会加载所有的rows,所以你的pageSize一定要和row相等,或者pageSize大于rows记录数。
后台数据是这个形式的,{“total”:11,”rows”:[{“value”:”123456″,”type”:”Integer”,”ziduan”:”pageInt”,”des”:”分页”}…..
]}
谢谢,已经解决了,我是在查询的时候带参数当前页和每页条数,再根据它们读取一页的数据,返回给ajax
datagrid如何在初始化就默认从指定的pageNumber开始分页,thx
管理员 世纪之光 : 2012年10月16日10:20:20 地下1层
@liny 你用的是url方式吧?不是有个pageNumber属性吗?控制初始化页码的。
datagrid没有加载到数据的时候,在grid中显示一行无数据,这个要怎么设置下。我使用的是loadData加载了条本地数据,但是在合并的时候,没有做好.
管理员 世纪之光 : 2012年10月30日11:44:29 地下1层
@liny 显示一行没数据是什么意思,如果rows元素对象为空的话,你用js判断一下啊,为空直接$(‘#tt’).datagrid(‘loadData’, {‘total’:0,”rows”:[]});清空数据,或者不要loadData。
grid如果没有加载到数据,列表就一片白,想来个提示:”暂无数据”@世纪之光
管理员 世纪之光 : 2012年10月30日14:08:00 地下3层
@liny “暂无数据”这种提示写在onLoadSuccess事件里面不就可以了吗,检查一下当前条数,为零的话就提示。
这个“暂无数据”要显示在列表中@世纪之光
管理员 世纪之光 : 2012年10月30日14:23:05 地下5层
@liny 你这个需求也太煞费苦心了吧?你还要合并所有列到一列,再次查询的时候你怎么办?完全蛋疼的需求啊。而且分页栏上也有个数的统计,你这是何必呢?
嗯,需求如此,再说有的列表不需要分页,如果查询没数据,页面啥也不显示那好像不太友好.@世纪之光
管理员 世纪之光 : 2012年10月30日18:35:43 地下7层
@liny 你合并列之后怎么办?再次查询的时候还要拆分列,如果拆分?没有现成接口给你拆。说句实话把暂无数据显示在datagrid里面,我不觉得任何有什么增加友好程度的意思,alert足矣。
页面加载datagird之前先将包含该datagrid的div hide(),然后再查询的时候再show(),这时候数据时加载出来了,但是页面上显示不出来。
这是什么原因?求指教!
管理员 世纪之光 : 2012年11月23日09:51:43 地下1层
不要随便用jquery方法操作datagrid的height,width,display这些属性,影响datagrid的正常计算。
针对你这种情况,在show之后调用一下 $(‘#tt’).datagrid(resize); 应该就可以了。
大家考虑过需求不能分页,一页显示1000条以上的数据吗?
我的出来在IE下直接卡死…想请教大数据一页展示怎么实现,但是不要太慢,控制在5s左右可以读取展示出来,求解决啊~~ 😕
管理员 世纪之光 : 2013年07月31日14:22:19 地下1层
最近正在着手研究如何提高datagrid的性能问题,这方面确实待提高。
管理员 世纪之光 : 2013年08月18日23:48:34 地下1层
datagrid的性能已经做了初步优化,请到以下文章阅读:
http://www.easyui.info/archives/1435.html
博主你好,我这边有个问题,使用url远程加载数据到datagrid,我想在onLoadSuccess里判断data是不是为空,结果发现在onLoadSuccess里的alert会出来两次,第一次alert出现在还没有数据加载进来前,第二次数据加载好后,很奇怪。后来我用$.fn.datagrid.defaults.view.onBeforeRender来看看,结果里面的alert也会出现两次。
管理员 世纪之光 : 2013年08月20日18:51:21 地下1层
你这个现象是典型的二次加载问题,检查一下你的代码,是不是设置了关键class,然后又在js里面构造datagrid了。
博主,我在用Layout=center里面有个datagrid,为什么两个控件的fit=true,datagrid的高度很小啊,目测只有50px,而不是适应整个center,请问怎么办啊?
管理员 世纪之光 : 2013年08月22日20:37:09 地下1层
这种问题完全可以自己通过调试css的问题解决。你高度没有fit,说明你datagrid的外层肯定加了一层没有fit的元素。
好文!帮助很大,谢谢 😛
好东西
确实有用啊,这么好的代码,我喜欢,受益了!
赞!顺便问个问题:我可以把json数据写成本地的.json文件,然后显示到页面中吗?怎么做 🙂
管理员 世纪之光 : 2013年12月03日09:18:54 地下1层
官网下载下来的demo里面,用的不都是本地的json文件么……demo都不认真看啊……
hi,楼主,你的文章让我受益匪浅。关于easyui加载本地数据这里,有个问题想咨询一下。reload和load这两个方法能否针对无url加载数据进行操作?如果可以的话,那么对于reload来说用不用进行什么设置?
我目前的场景是采用ajax调用后台数据,然后采用无url方式,即loadData进行数据对datagrid进行填充。之后由于要增删改需要对datagrid进行重新加载数据,这一部我想采用reload进行重新加载,没有成功。所以有上文一问,这里的reload是否只能针对url进行加载?
如果楼主能帮忙回答,不胜感激。
分页其实不用那么麻烦框架上有自带的,不过还是谢谢分享 😛
管理员 世纪之光 : 2014年03月06日13:49:55 地下1层
URL方式分页是自带的,但是不适用于loadData方式。
楼主你好,看来您对于datgrid的使用很有心得,我想问下,如果datagrid所在的容器是隐藏的,display:none,这个时候如果再使用loadData方法给datagrid更新数据,datagrid的高度变成0了(测试环境:火狐和IE8),请问有什么办法解决?
管理员 世纪之光 : 2014年04月01日13:44:44 地下1层
解决方式一:
将datagrid的fit属性设置为true;
解决方式二:
在你所说的“datagrid的容器”由隐藏变为显示后调用panel的resize方法
能不能给个完整的例子看看效果………….
管理员 世纪之光 : 2014年04月07日16:05:55 地下1层
因为博客空间是PHP的,我对PHP一知半解,不太会写,所以给不出完整的例子和demo
前天没网,想个不改源码的分页方式,跟楼主的做法不谋而合,觉得下面这段代码很好,我的做法是直接将datagrid需要的json组织好,总感觉怪怪的,向楼主学习了
//异步获取数据到javascript对象,入参为查询条件和页码信息
var oData = getAjaxDate(“orderManageBuz”,”qryWorkOrderPaged”,queryCondition,gridOpts);
//使用loadDate方法加载Dao层返回的数据
$(‘#tt’).datagrid(‘loadData’,{“total” : oData.page.recordCount,”rows” : oData.data});
参考了
博主,你好,我在用$(‘#gd’).datagrid(‘load’,{‘param1′:’param1’}) 执行按条件查询时,当查询参数能查出结果时都正常,只load一次数据,但是当输入的查询条件没有符合的记录时,会load两次,并且两次的分页参数page不一样,第一次正常的传入page=1,第二次传入page=0,实在是没弄明白怎么回事,说明:我没使用class渲染datagrid
管理员 世纪之光 : 2014年09月29日15:05:05 地下1层
在datagrid源码的ajax方法附近加断点调试吧,看看两次的调用堆栈,然后分析请求两次的原因。
大侠:datagrid的完整格式是不是这样的,求解。。。{ “columns”:”[[ {field:’field1′,’title’:’title1′},{…} ]]”,data:[{page:”pageIndex”,total:”totalNum”,rows:[{name1:value,name2:value},{…}]}]}
管理员 世纪之光 : 2014年10月30日17:30:40 地下1层
data里面不需要page信息
您好 getAjaxDate 这点我很不明白 什么叫做异步的加载js对象 为什么传入的参数是上述你写的那样 不能写其他的么 js这块我不太熟 还望赐教
管理员 世纪之光 : 2015年05月03日23:39:08 地下1层
去查查javascript语言的ajax技术的相关知识。
写的很好,多多学习 🙂
我就看看
$(‘#data_list_table’).datagrid(‘getPager’).pagination({
onSelectPage:function(pageNumber, pageSize){
query_data_list(pageNumber, pageSize);
}
});
//by url – 能充分利用datagrid的显示特性,如:更新paging,rownumbers,显示tbody加载效果,
function query_data_list(pageNumber,pageSize){
$(‘#data_list_table’).datagrid(‘options’).url=”xxx.php”;
$(‘#data_list_table’).datagrid(‘options’).queryParams={pagesize:xxx,pageNo:xxx, other query param};
$(“#data_list_table”).datagrid(‘reload’);//不要使用load,无法翻页
}
//by lodaData – 能更好的自行判断控制,但会损失datagrid的一些方便特性。
function query_data_list(pageNumber,pageSize){
$.post(“xxx.php”,{pagesize:xxx,pageNo:xxx, other query param},
function(data) {
//check data, then call $(“#data_list_table”).datagrid(‘loadData’,data);
//无loading效果,rownumbers也只是第一页。
}
}
很棒的贴子!该有的细节都有了,收藏!
我想问下动态修改datagrid的columns,页面会加载两次,第一次是多余的,我想问下怎么解决
那个在去掉loading图片的时候重写了onloadSuccess方法,这个会不会覆盖掉原来的?