【easyui】treegrid逐级加载源码
当初看这源码的目的是:
1、treegrid是怎么实现逐级加载树结构的。
解: 见demo,主要就是点击节点的时候会请求后台。
2、treegrid加载后,第二次展开节点会不会再次请求后台。
解:第二次展开节点不会再请求后台。
没记错的话,貌似是第一次点击节点 –> 请求后台 –> 根据响应的数据构建div,形成树结构。
再第二次点击的时候:点击节点所在的div的下一个同级div的class是tr.treegrid-tr-tree的话,表示已加载过其子节点数据。则不需要再次请求后台。
3、对js不是那么的熟悉,顺便学习下js,看treegrid的实现思路和了解一些对js不知道的东西。
a) 不管是easyui还是jquery都大量使用了回调函数。
b) 都不只直接用的function的参数,而是通过js内置的arguments[i]来判断运用。(jquery貌似用的多,在深/浅复制那)
如果对js不是很清楚,可以大致浏览下 JS总结 – 乱 。
// demo.js $(function() {
$('#datagrid').treegrid({
url:'loanOrganization/queryLoanOrganizationJSONList',
idField:'id',
treeField:'text',
nowrap: false,
rownumbers: true,
toolbar: '#toolBar',
animate:true,
collapsible:true,
columns:[[
{field:'id',title:'合作机构id',width:300,hidden:true},
{field:'text',title:'合作机构名称',width:300,iconCls:"icon-sum"},
{field:'ext1',title:'子节点数量',width:200,
formatter: function(value,row,index){
return value =='0' ? '' : value;
}
},
{field:'ext2',title:'排序字段',width:100,sortable:true}
]],
loadFilter: function(result){ return result.data;},
onClickRow:function(row){
console.info("onClickRow:当用户点击一个节点时触发.");
},
onBeforeLoad:function(row, param){
console.info("onBeforeLoad:一个请求去加载数据之前触发, 返回false将取消加载动作.");
},
onLoadSuccess:function(row,data){
console.info("onLoadSuccess:数据加载成功之后触发.");
},
onLoadError:function(){
console.info("onLoadError:数据加载失败之后触发,arguments 参数和jQuery.ajax的error函数一样.");
},
onBeforeExpand:function(row){ //每次展开前都会调用
//动态设置展开查询的url
var url = 'loanOrganization/queryLoanOrganizationJSONList?parentId='+row.id;
$("#datagrid").treegrid("options").url = url;
return true; //返回false表示停止展开节点
},
onExpand : function(row){ //每次展后都会调用;传入的row已经包含了 children
var children = $("#datagrid").treegrid('getChildren',row.id);
if(children.length<=0){
row.leaf=true;
$("#datagrid").treegrid('refresh', row.id);
}
},
onContextMenu: function(e,row){
e.preventDefault();
$(this).treegrid('unselectAll');
$(this).treegrid('select', row.id);
$('#mm').menu('show', {
left: e.pageX,
top: e.pageY
});
},
onDblClickRow: function(row){
edit();
}
});
}); //$(function(){...}) end
Easyui.js源码 版本:1.3.2
function _6db(_6dc,_6dd){ //内部函数_6df(cc)
var opts=$.data(_6dc,"treegrid").options;
var tr=opts.finder.getTr(_6dc,_6dd);
var hit=tr.find("span.tree-hit");
var row=find(_6dc,_6dd); if(hit.length==0){
return;
}
if(hit.hasClass("tree-expanded")){
return;
}
if(opts.onBeforeExpand.call(_6dc,row)==false){// 触发onBeforeExpand
return;
}
hit.removeClass("tree-collapsed tree-collapsed-hover").addClass("tree-expanded");
hit.next().addClass("tree-folder-open");
// 点击节点所在的div的下一个同级div的class是tr.treegrid-tr-tree的话,表示已加载过其子节点数据。则不需要再次请求后台。
var _6de=tr.next("tr.treegrid-tr-tree");
// if为true时,不会再次请求后台(即该节点的子节点数据已被加载过)
if(_6de.length){
var cc=_6de.children("td").children("div");
_6df(cc);
}else{ // _6de==Object[] 要请求后台加载数据
_6a8(_6dc,row[opts.idField]);
var _6de=tr.next("tr.treegrid-tr-tree");
var cc=_6de.children("td").children("div");
cc.hide();
// _699() 内部有ajax请求后台
_699(_6dc,row[opts.idField],{id:row[opts.idField]},true,function(){
if(cc.is(":empty")){
_6de.remove();
}else{
_6df(cc);
}
});
}
function _6df(cc){
row.state="open";
if(opts.animate){
cc.slideDown("normal",function(){
$(_6dc).treegrid("autoSizeColumn");
_69a(_6dc,_6dd);
opts.onExpand.call(_6dc,row);
});
}else{
cc.show();
$(_6dc).treegrid("autoSizeColumn");
_69a(_6dc,_6dd);
opts.onExpand.call(_6dc,row);
}
};
};
function find(_6d6,_6d7){ // _6d7 == idField
var opts=$.data(_6d6,"treegrid").options;
var data=$.data(_6d6,"treegrid").data;
var cc=[data];
while(cc.length){
//shift() 方法用于把数组的第一个元素从其中删除,并返回第一个元素的值。
var c=cc.shift();
for(var i=0;i<c.length;i++){//
var node=c[i];
if(node[opts.idField]==_6d7){
return node;
}else{
if(node["children"]){
cc.push(node["children"]);
}
}
}
}
return null;
};
function _699(_6b7,_6b8,_6b9,_6ba,_6bb){
var opts=$.data(_6b7,"treegrid").options;
var body=$(_6b7).datagrid("getPanel").find("div.datagrid-body");
if(_6b9){
opts.queryParams=_6b9;
}
var _6bc=$.extend({},opts.queryParams);
if(opts.pagination){
$.extend(_6bc,{page:opts.pageNumber,rows:opts.pageSize});
}
if(opts.sortName){
$.extend(_6bc,{sort:opts.sortName,order:opts.sortOrder});
}
var row=find(_6b7,_6b8);
if(opts.onBeforeLoad.call(_6b7,row,_6bc)==false){
return;
}
var _6bd=body.find("tr[node-id="+_6b8+"] span.tree-folder");
_6bd.addClass("tree-loading");
$(_6b7).treegrid("loading"); //请求加载tree数据,根据treegrid定义的url(在onBeforeExpand中修改了的url)。
var _6be=opts.loader.call(_6b7,_6bc,
function(data){ // loader中ajax成功请求的回调函数
_6bd.removeClass("tree-loading");
$(_6b7).treegrid("loaded");
_6af(_6b7,_6b8,data,_6ba);
if(_6bb){
_6bb();
}
},function(){
_6bd.removeClass("tree-loading");
$(_6b7).treegrid("loaded");
opts.onLoadError.apply(_6b7,arguments);
if(_6bb){
_6bb();
}
});
if(_6be==false){
_6bd.removeClass("tree-loading");
$(_6b7).treegrid("loaded");
}
};
$.fn.treegrid.defaults=$.extend({},$.fn.datagrid.defaults,
{ treeField:null,
animate:false,
singleSelect:true,
view:_709,
//_73a:请求参数 _73b:ajax success回调函数 _73c:ajax error回调函数
loader:function(_73a, _73b, _73c){
var opts=$(this).treegrid("options");
if(!opts.url){
return false;
}
$.ajax({type:opts.method,
url:opts.url,
data:_73a,
dataType:"json",
success:function(data){
_73b(data);
},
error:function(){
_73c.apply(this,arguments);
}
});
},loadFilter:function(data,_73d){
return data;
}, ...
function _6af(_6b0,_6b1,data,_6b2){
var opts=$.data(_6b0,"treegrid").options;
var dc=$.data(_6b0,"datagrid").dc;
data=opts.loadFilter.call(_6b0,data,_6b1);
var node=find(_6b0,_6b1);
if(node){
var _6b3=opts.finder.getTr(_6b0,_6b1,"body",1);
var _6b4=opts.finder.getTr(_6b0,_6b1,"body",2);
var cc1=_6b3.next("tr.treegrid-tr-tree").children("td").children("div");
var cc2=_6b4.next("tr.treegrid-tr-tree").children("td").children("div");
}else{
var cc1=dc.body1;
var cc2=dc.body2;
}
if(!_6b2){
$.data(_6b0,"treegrid").data=[];
cc1.empty();
cc2.empty();
}
if(opts.view.onBeforeRender){
// onBeforeRender中处理了treeJson
opts.view.onBeforeRender.call(opts.view,_6b0,_6b1,data);
}
opts.view.render.call(opts.view,_6b0,cc1,true);
opts.view.render.call(opts.view,_6b0,cc2,false);
if(opts.showFooter){
opts.view.renderFooter.call(opts.view,_6b0,dc.footer1,true);
opts.view.renderFooter.call(opts.view,_6b0,dc.footer2,false);
}
if(opts.view.onAfterRender){
opts.view.onAfterRender.call(opts.view,_6b0);
}
opts.onLoadSuccess.call(_6b0,node,data);
if(!_6b1&&opts.pagination){
var _6b5=$.data(_6b0,"treegrid").total;
var _6b6=$(_6b0).datagrid("getPager");
if(_6b6.pagination("options").total!=_6b5){
_6b6.pagination({total:_6b5});
}
}
_69a(_6b0);
_6a2(_6b0);
$(_6b0).treegrid("autoSizeColumn");
};
function _69a(_69b,_69c){
var opts=$.data(_69b,"datagrid").options;
var dc=$.data(_69b,"datagrid").dc;
if(!dc.body1.is(":empty")&&(!opts.nowrap||opts.autoRowHeight)){
if(_69c!=undefined){
var _69d=_69e(_69b,_69c);
for(var i=0;i<_69d.length;i++){
_69f(_69d[i][opts.idField]);
}
}
}
$(_69b).datagrid("fixRowHeight",_69c);
function _69f(_6a0){
var tr1=opts.finder.getTr(_69b,_6a0,"body",1);
var tr2=opts.finder.getTr(_69b,_6a0,"body",2);
tr1.css("height","");
tr2.css("height","");
var _6a1=Math.max(tr1.height(),tr2.height());
tr1.css("height",_6a1);
tr2.css("height",_6a1);
};
};
function _6a2(_6a3){
var dc=$.data(_6a3,"datagrid").dc;
var opts=$.data(_6a3,"treegrid").options;
if(!opts.rownumbers){
return;
}
dc.body1.find("div.datagrid-cell-rownumber").each(function(i){
$(this).html(i+1);
});
};
function _69e(_6c6,_6c7){
var opts=$.data(_6c6,"treegrid").options;
var body=$(_6c6).datagrid("getPanel").find("div.datagrid-view2 div.datagrid-body");
var _6c8=[];
if(_6c7){
_6c9(_6c7);
}else{
var _6ca=_6c1(_6c6);
for(var i=0;i<_6ca.length;i++){
_6c8.push(_6ca[i]);
_6c9(_6ca[i][opts.idField]);
}
}
function _6c9(_6cb){
var _6cc=find(_6c6,_6cb);
if(_6cc&&_6cc.children){
for(var i=0,len=_6cc.children.length;i<len;i++){
var _6cd=_6cc.children[i];
_6c8.push(_6cd);
_6c9(_6cd[opts.idField]);
}
}
};
return _6c8;
}
var _709 = $.extend({},$.fn.datagrid.defaults.view,
{onBeforeRender : function(_72e, _72f, data) {
if (!data) {
return false;
}
var opts = $.data(_72e, "treegrid").options;
if (data.length == undefined) {
if (data.footer) {
$.data(_72e, "treegrid").footer = data.footer;
}
if (data.total) {
$.data(_72e, "treegrid").total = data.total;
}
data = this.transfer(_72e, _72f, data.rows);
} else {
function _730(_731, _732) {
for ( var i = 0; i < _731.length; i++) {
var row = _731[i];
row._parentId = _732;
if (row.children && row.children.length) {
_730(row.children,row[opts.idField]);
}
}
};
_730(data, _72f);
}
var node = find(_72e, _72f);
if (node) {
if (node.children) {
// concat() 方法用于连接两个或多个数组。
// 该方法不会改变现有的数组,而仅仅会返回被连接数组的一个副本。
node.children = node.children.concat(data);
} else {
node.children = data;
}
} else {
$.data(_72e, "treegrid").data = $.data(_72e,
"treegrid").data.concat(data);
}
if (!opts.remoteSort) {
this.sort(_72e, data);
}
this.treeNodes = data;
this.treeLevel = $(_72e).treegrid("getLevel", _72f);
},...}
【easyui】treegrid逐级加载源码的更多相关文章
- springMVC容器加载源码分析
springmvc是一个基于servlet容器的轻量灵活的mvc框架,在它整个请求过程中,为了能够灵活定制各种需求,所以提供了一系列的组件完成整个请求的映射,响应等等处理.这里我们来分析下spring ...
- composer 自动加载源码解析
一直在用 composer,最近想看一下具体的原理是什么,就仔细阅读了一下源码,一下是个人理解.在看该文章前最好了解一下 PSR-4 自动加载规范 引入类自动加载文件 # 加载类自动加载文件 requ ...
- 2.3 spring5源码系列---内置的后置处理器PostProcess加载源码
本文涉及主题 1. BeanFactoryPostProcessor调用过程源码剖析 2. 配置类的解析过程源码 3. 配置类@Configuration加与不加的区别 4. 重复beanName的覆 ...
- mybatis配置加载源码概述
Mybatis框架里,有两种配置文件,一个是全局配置文件config.xml,另一个是对应每个表的mapper.xml配置文件.Mybatis框架启动时,先加载config.xml, 在加载每个map ...
- easyui treegrid逐步加载
$("#bomStructureTable").treegrid({ url : "systemcontroller?id=10007",//首次查询路径 qu ...
- eclipse中自动加载源码的方法
1.选中项目右键properties--java build path--Libraries--Add External class Folder 找到项目将项目添加进去 2.然后就是这样 3.OK
- SpringBoot-静态资源加载-源码
目录 静态资源映射规则 什么是webjars 呢? 第二种静态资源映射规则 参考链接 静态资源映射规则 SpringBoot中,SpringMVC的web配置都在 WebMvcAutoConfigur ...
- Android动态加载字节码
概述 面对App业务逻辑的频繁变更,如果每一次改变都对App进行一次升级,会降低App的用户体验,那么App进行模块化升级(这里与增量升级是不同的)是很好的解决方案,让用户在完全无感觉的情况下改变Ap ...
- iOS下使用SHA1WithRSA算法加签源码
首先了解一下几个相关概念,以方便后面遇到的问题的解决: RSA算法:1977年由Ron Rivest.Adi Shamirh和LenAdleman发明的,RSA就是取自他们三个人的名字.算法基于一个数 ...
随机推荐
- ArrayList 并发操作 ConcurrentModificationException 异常
1.故障现象 ArrayList在迭代的时候如果同时对其进行修改就会抛出java.util.ConcurrentModificationException异常 2.故障代码 public class ...
- Deeplab
Deeplab系列是谷歌团队的分割网络. DeepLab V1 CNN处理图像分割的两个问题 下采样导致信息丢失 maxpool造成feature map尺寸减小,细节信息丢失. 空间不变性 所谓空间 ...
- Redis(九):主从复制的设计与实现解析
前面几篇我们已经完全理解了redis的基本功能的实现了. 但单靠基本功能实现,往往还是称不上优秀的项目的.毕竟,我们现在面对的都是复杂的环境,高并发的场景,大数据量的可能. 简而言之,现在的系统一般都 ...
- 2020牛客寒假算法基础集训营4 D:子段异或
D : 子段异或 考察点 : 位运算,前缀和,异或的性质和应用 坑点 : 0 - L 的异或值是 0 的话也是一个区间 相同的值可能有多个,那么这时候区间就会有多个(x * (x + 1) / 2) ...
- MATLAB添加工具箱及无法连接到MathWorks问题
版本信息:官网下载的MATLAB R2019b 学生版 操作系统:Windows 10 在安装MATLAB时,需要我们自行选择要安装工具箱,如何在已安装MATLAB后添加当初没有选择安装的工具箱呢?第 ...
- .NET Core之单元测试(四):Fluent Assertions的使用
目录 什么是Fluent Assertions 待测试API 测试用例 什么是Fluent Assertions Fluent Assertions 是 .NET 平台下的一组扩展方法,用于单元测试中 ...
- C语言RH850 F1L serial bootloader和C#语言bootloader PC端串口通信程序
了解更多关于bootloader 的C语言实现,请加我QQ: 1273623966 (验证信息请填 bootloader),欢迎咨询或定制bootloader(在线升级程 ...
- .net 微服务实践
l 前言 本文记录了我的一次.net core 微服务架构实践经验,以及所用到的技术 l 优点 每个服务聚焦于一块业务,无论在开发阶段或是部署阶段都是独立的,更适合被各个小团队开发维护,团队对服务 ...
- PMP--2.1 商业论证(经济可行性研究报告)
####################################################### PS:半个月没有更新文档,因为是有点单线程,在整理启动过程组和规划过程组的内容,在规划规 ...
- 关于elementui的table组件单元格的内容自定义写法
------------恢复内容开始------------ 记录老哥的写法 columns是表格的配置文件 在表格渲染的时候通过renderTableCell传入表格的row以及配置文件中的rend ...