【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);
    },...}
posted @ 2016-10-25 20:52  淡丶无欲  阅读(5176)  评论(2编辑  收藏  举报