当初看这源码的目的是:

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);
},...}

最新文章

  1. form表单序列化后的数据转json对象
  2. DataList删除操作
  3. 第五章 与众不同的this
  4. js----对象的创建
  5. linux查看在线用户 who命令参数及用法
  6. hdu 3062 2-sat入门题
  7. 华为HG8245 电信 光猫破解获取超级密码
  8. 微信bug:建议了解,不要实验,不要手贱,不要。。。。
  9. Oracle创建表时Storage参数具体含义
  10. zabbix配置微信报警
  11. C# 如何在PDF中绘制不同风格类型的文本
  12. 【网络】IP子网划分详解
  13. Spark机器学习(上)
  14. c++学习day4
  15. 潭州课堂25班:Ph201805201 第十一课 继承,多继承和魔术方法,属性和方法 (课堂笔记)
  16. python获得命令行参数的方法
  17. security和oauth2.0的整合
  18. PostgreSQL参数学习:vacuum_defer_clean_age
  19. win8扁平风格的物流公司网站后台管理模板——后台
  20. SQL语句之数据库操作

热门文章

  1. java12类的无参方法
  2. Go语言实现:【剑指offer】二叉树中和为某一值的路径
  3. Go语言实现:【剑指offer】正则表达式匹配
  4. SHELL下打包文件
  5. 对C语言整数类型的一点理解
  6. 五分钟了解抽象语法树(AST)babel是如何转换的?
  7. JS实现斐波那契数列的几种方法
  8. 内部类(innerclasses)
  9. pikachu-SQL注入漏洞
  10. Linux发行版Ubuntu下的Python开发环境的配置