當初看這源碼的目的是:
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); },...}