`

ExtJS中的树的使用和总结

阅读更多

ExtJS中的树的使用和总结

 

一.TreePanel 配置参数:

root:Ext.tree.TreeNode 		//根节点
loader:Ext.tree.TreeLoader 	//数据加载器
checkModel:"single" 		//复选框只能单选,多选为:multiple,级联:cascade  
trackMouseOver:false 		//是否只有叶子节点可选
rootVisible:false 			//false不显示根节点,默认为true
autoScroll:true 			//超过范围自动出现滚动条
animate:true 				//展开和收缩时的动画效果
enableDrag:true 			//树的节点可以拖动,注意不是Draggable
enableDD:true 				//不仅可以拖动,还可以通过Drag改变节点的层次结构(drap和drop)
enableDrop:true 			//仅仅drop
lines:true 					//节点间的虚线条
useArrows:true 				//侧三角,false则为"+-"

 

二.TreeNode的基本配置参数:

id:"id"						//节点ID
text:"节点文本" 			//节点显示的文本
cls:"folder/file"			//节点显示的样式:文件夹或文件
pid:"id"					//父节点的ID
leaf:true 					//是否是叶子节点
expanded:fasle 				//是否展开,默认不展开
checked:false 				//true则在text前有个选中的复选框,false则text前有个未选中的复选框,默认没有任何框框
href:"http://www.123.com"	//节点的链接地址
hrefTarget:"mainFrame" 		//打开节点链接地址默认为blank,可以设置为iframe名称id,则在iframe中打开
qtip:"提示" 				//提示信息,不过要有Ext.QuickTips.init();
singleClickExpand:true 		//用单击文本展开,默认为双击

 

三.树节点的数据分析:

1.节点数据分为父节点和子节点,父节点需要以文件夹形式显示。

2.子节点与父节点的关联通过pid实现

例如:

[
  {
    "id": "01",
    "text": "企业科",
    "cls": "folder",
    "children": [
      {
        "id": "qyk1",
        "text": "企业科一号用户",
        "cls": "file",
        "pid": "01",
        "leaf": true,
        "autoid": 0,
        "expanded": false
      },
      {
        "id": "qyk2",
        "text": "企业库二号用户",
        "cls": "file",
        "pid": "01",
        "leaf": true,
        "autoid": 0,
        "expanded": false
      }
    ],
    "leaf": false,
    "autoid": 0,
    "expanded": false
  }
]

注意一些属性名称:

 

四.实例分析:

1.创建触发域:

var selectedAuditRow;//定义全局变量————获取点击列表某一行时通过复选框获得的行号。  
     
/*1.创建触发域*/  
var auditTrigger = new Ext.form.TriggerField({  
    emptyText:"请选择...",  
    allowBlank:false,  
    readOnly:true,  
    onTriggerClick:function(e){    //单击触发按钮触发的事件  
        selectedAuditRow = auditSm.getSelected();  
        auditTreeWin.show();  
        auditRoot.reload();     //每次点击触发域时重新加载树
    }  
});  

 

2.创建Record:

/*2.创建Record*/  
var auditRecord = new Ext.data.Record.create([  
    {name:"did",type:"string"},  
    {name:"dname",type:"string"},  
    {name:"sdid",type:"string"},  
    {name:"sdname",type:"string"},  
    {name:"title",type:"string"},  
    {name:"orderid",type:"int"},  
    {name:"auditUserId",type:"string"}
]);

 

3.创建Store:

/*3.创建Store*/  
var auditStore = new Ext.data.Store({  
    url:"getAuditDetail.up?doType=getAuditDetail",  
    reader: new Ext.data.JsonReader({  
        root:"data"  
    },auditRecord)  
});

 

4.创建表格复选框和ColumnModel:

/*4.创建ColumnModel*/ 
var auditSm = new Ext.grid.CheckboxSelectionModel();
var auditCm = new Ext.grid.ColumnModel({
    columns:[
        auditSm,
        {
            header:"编号",
            dataIndex:"id",
            hidden:true
        },{
            header:"部门编号",
            dataIndex:"did",
            hidden:true
        },{
            header:"部门名称",
            dataIndex:"dname",
            width:170,
            renderer:function(v){
                return dname;
            }
        },{
            header:"科室编号",
            dataIndex:"sdid",
            hidden:true
        },{
            header:"科室名称",
            dataIndex:"sdname",
            width:170,
            renderer:function(v){
                return sdname;
            }
        },{
            header:"流程名称",
            dataIndex:"title",
            editor:new Ext.form.TextField({   
                id:"title"  
            }),
            width:190
        },{
            header:"流程顺序",
            dataIndex:"orderid",
            width:140
        },{
            id:"auditUserId",
            header:"审核用户ID",
            dataIndex:"auditUserId",
            editor:auditTrigger,
            width:195
        }
    ]
});

 

5.创建GridPanel:

/*5.创建GridPanel*/ 
var auditGrid = new Ext.grid.EditorGridPanel({
title:"审核流程明细",
store:auditStore,
cm:auditCm,
sm:auditSm,
border:true,
bodyBorder:true,
split: true,
clicksToEdit:1,    
stripeRows: true,//斑马线
loadMask:{msg:"正在加载数据,请稍后......"},
height:250,
tbar:[
    {  
        text:"保存流程",  
        iconCls:"save",
        handler:saveAuditDetail
    },{  
        text:"增加流程",  
        iconCls:"add",  
        handler:function(){  
            if(sdid == 0) {
                Ext.Msg.alert("系统提示","请先选择科室再增加审核流程");
                return;
            }
            var newAudit = new auditRecord({   //此处创建新的Record  
                    did:did,//此处的did,dname,sdid,sdname是全局变量,在其他地方赋值,此处不详述
                    dname:dname,
                    sdid:sdid, 
                    sdname:sdname,
                    title:'',  
                    orderid:order,  
                    auditUserid:''
                });  
                auditGrid.stopEditing();         //关闭表格的编辑状态  
                auditStore.add(newAudit);  
                auditGrid.startEditing(0, 0);    //激活第一行第一列的编辑状态  
        }
    },{  
        text:"删除流程",  
        iconCls:"remove",
        handler:removeAuditDetail
    }  
      ]
});

 

6.创建树:

/*6.创建树*/  
//6.1 定义根节点  
var auditRoot = new Ext.tree.AsyncTreeNode({  
    id:'tree-root',  
    text:"部门",  
    expanded:true,    //根节点默认展开(注意和TreePanel中的rootVisible:true的联系)
    draggable:false   //根节点不可拖动  
});  
//6.2 定义节点数据加载器  
var auditLoader = new Ext.tree.TreeLoader({  
    dataUrl:'getKeshiUsersByGrade.up?doType=getKeshiUsersByGrade',  //此处不是url,和Store的Proxy不同  
    baseParams :{pid:''},  
    baseAttrs:{uiProvider:Ext.tree.TreeCheckNodeUI} //必须有该项,不然树节点无法出现选择框  
});  
//6.3 定义数据加载前触发方法  
auditLoader.on("beforeload",function(treeLoader,node){  
    auditRoot.setText(dname);     //加载前重新设置树的根节点的名称
    treeLoader.baseParams.pid = node.id;  
    treeLoader.baseParams.did = did;  //加载前给定pid和did参数
},this);  

//6.4 定义树形面板,用于显示数据  
var auditTree = new top.Ext.tree.TreePanel({    /**注意top!!!*/  
    root:auditRoot,      //根节点  
    loader:auditLoader,  //数据加载器  
    checkModel:"single", //复选框只能单选,多选为:multiple,级联:cascade  
    rootVisible:true,    //显示根节点  
    autoScroll:true,      
    animate:false,  
    enableDD:false,      //不允许子节点拖动  
    onlyLeafCheckable:true,  
    /* trackMouseOver:false,
    useArrows:true, */
    width:250,  
    listeners:{"click":function(node){  
        if(!node.isLeaf()){   
            node.toggle(); //点击可展开可收缩  
        }else{
	node.ui.toggleCheck();
}   
    }}  
});  

注意:

1.树的加载器里必须加上uiProvider,用于显示复选框

 

2.加载前传入参数,在后台通过request.getParameter("param")方式获取

 

后台取数:

 

7.创建存放树的窗口:

var auditTreeWin = new top.Ext.Window({    /**注意top!!!*/  
    title:"用户选择",  
    layout:"fit",  
    closeAction:"hide",  
    modal:true,  
    width:250,  
    height:250,  
    items:auditTree,  
    buttons:[  
        {  
            text:"确定",  
            handler:function(e){  /*点击选择树节点并将值显示在触发域的方法!*/
                var node = auditTree.getChecked();    //获取被选中的树节点  
                if(!node || node.length < 1){  
                    top.Ext.Msg.alert("系统提示","请选择用户!");  
                    return;  
                }  
                var name = new Array();  
                var value = new Array();  
                for (var i = 0; i < node.length; i++) {  
                    name.push(node[i].text);  
                    value.push(node[i].id);  
                }  
                var data = selectedAuditRow.data;    //获取选择的行的Record的Data数据对象  
                /*data["auditUserId"]= name.join(); —— —— 此处用这种方式给触发域赋值出错!!!必须用下面的方式!!! */    
                auditTrigger.setValue(name.join());  
                auditTreeWin.hide();  
            }  
        },{  
            text:"取消",  
            handler:function(){  
                auditTreeWin.hide();  
            }  
        }  
    ]  
});  

注意:此处的树窗口和树面板需要加上“top”,否则无法显示。




 

8.创建单击触发域显示树窗口并显示选中项被勾选的方法:

/* 单击触发域打开树窗口并显示勾选项 */
auditTrigger.onTriggerClick = clickTriggerFun;
function clickTriggerFun(e){
	auditTreeWin.show();
	var parentNodes = auditRoot.childNodes;
	if(parentNodes.length > 0) {
		showCheckedNode(parentNodes);
	}
	else {
		loadTree();//节点为0,则先加载树
	}
}

/* 加载科室用户并勾选对应项 */
function loadTree(){
	auditLoader.on("load",function(treeLoader,node){
		showCheckedNode(node.childNodes);
	});
}

/* 勾选对应的选中项,并展开选中项的父目录 */
function showCheckedNode(parentNodes){
	//先展开再收缩父节点,让子节点充分显示
	for (var i = 0; i < parentNodes.length; i++) {
		parentNodes[i].expand();
		parentNodes[i].collapse();
	}
	//先循环清楚全部勾选项
	for (var i = 0; i < parentNodes.length; i++) {
		var childNodes = parentNodes[i].childNodes;
		for (var j = 0; j < childNodes.length; j++) {
			childNodes[j].ui.toggleCheck(false);
		}
	}
	//将触发域中的内容字符串分割为一个数组
	var tgValue = auditTrigger.getValue();
	childNodes = auditRoot.childNodes;
	var checkedArr = null;
	if(tgValue != null) {
		checkedArr = tgValue.split(",");
	}
	//循环对比,相对应的进行勾选
	if(checkedArr != null && checkedArr.length > 0) {
		for (var i = 0; i < parentNodes.length; i++) {
			var childNodes = parentNodes[i].childNodes;
			for (var j = 0; j < childNodes.length; j++) {
				var text = childNodes[j].text;
				for (var k = 0; k < text.length; k++) {
					if(checkedArr[k] == text) {
						childNodes[j].ui.toggleCheck(true);//勾选
						childNodes[j].parentNode.expand();//展开父节点
					}
				}
			}
		}
	}
}

 

9.创建保存科室审核流程明细的方法,只保存修改过的信息:

/*创建保存科室审核流程明细的方法,只保存修改过的信息*/  
function saveAuditDetail(){  
    var rcds = auditStore.getModifiedRecords();     //获取修改过的记录集Records  
    if(rcds&&rcds.length>0){  
        Ext.Msg.wait("正在保存...");  
        var rows=new Array();  
        for(var i=0;i<rcds.length;i++){  
            var rs = rcds[i];    //获取指定下标的某一行的记录Record  
            var row=new Object();  
            var fields=rs.data;    //获取该行记录的数据Data  
            row = {did:fields.did,sdid:fields.sdid,title:fields["title"],orderid:fields["orderid"],auditUserId:fields["auditUserId"]};  
            rows.push(row);    //注意此处获取属性方式:obj.id或者obj["id"]皆可  
        }                      //因为此处obj是data,是一个对象,这些id,name都是data的属性  
                               //如果直接用record,则可以用它在Extjs中定义的get方法:rs.get("id")  
        Ext.Ajax.request({     
            url: 'updateAuditDetail.up?doType=updateAuditDetail',     
            method:'POST',  
            timeout:30000,    
            success: result,  
            failure: function(){Ext.Msg.alert('失败','未成功提交数据!'); },  
            params:{updateSets :Ext.encode(rows)}   //将数组转化为JSON字符串
        });  
        function result(response, options){  
            var result = Ext.util.JSON.decode(response.responseText);  
            if(result.success){  
                Ext.Msg.hide();  
                Ext.Msg.show({  
                        title:'成功',  
                        msg: '数据保存成功',  
                        buttons: Ext.Msg.OK,  
                        icon: Ext.MessageBox.INFO  
                });   
                //保存成功后刷新修改过的脏数据。  
                auditStore.rejectChanges();  
                auditStore.reload();  
           }else{  
              Ext.Msg.hide();  
              Ext.Msg.alert('失败','保存数据未成功!');  
           }  
        }   
    }  
}  

注意:Ext.encode(arr)方法可将数组转化为JSON字符串

 

10.创建删除科室审核流程明细的方法,删除复选框勾选的记录:

/*创建删除科室审核流程明细的方法,删除复选框勾选的记录*/  
function removeAuditDetail(){  
    var rcs = auditGrid.getSelectionModel().getSelections();  
    if(!rcs||rcs.length<1){  
        Ext.Msg.alert("提示","请先选择要删除的行");  
        return;  
    }  
    else{  
        Ext.Msg.confirm("确认删除","请确认是否删除选中的科室审核流程明细?",function(btn){  
            if(btn == "yes"){//选中"是"的按钮  
                Ext.Msg.wait("正在删除...");  
                var ids = new Array();  
                for (var i = 0; i < rcs.length; i++) {  
                    ids.push(rcs[i].get("id"));  
                }  
                //异步发请求  
                Ext.Ajax.request({  
                    url:"deleteAuditDetails.up?doType=deleteAuditDetails",  
                    method:"POST",  
                    params:{auditIds:ids.join(",")},  
                    success:function(response,option){  
                        var result = Ext.decode(response.responseText);  
                        if (result.success) {  
                            Ext.Msg.alert("成功","选中的科室审核流程明细已成功删除!");  
                            auditStore.rejectChanges();  
                            auditStore.reload();  
                        }  
                    },  
                    failure:function(response,option){  
                        Ext.Msg.alert("失败","删除过程中发生错误!");  
                    }  
                });  
            }  
        });  
    }  
}  

注意:Ext.decode(jsonStr)方法可将JSON字符串转化为对象或数组

 

11.查询、保存(更新)、删除的Servlet:

if ("getAuditDetail".equals(action)) {  //查询
    String sdid = request.getParameter("sdid");
    UserPostDao userPostDao = new UserPostDao();
    List auditDetails = userPostDao.getKeshiAuditDetailsBySdid(sdid);
    String data = JSON.toJSONString(auditDetails);  //集合转Json字符串
    json = "{\"data\":" + data + "}"; 
    response.setContentType("text/json;charset=UTF-8");  
    out = response.getWriter();  
    out.print(json);        
    out.close();
    return;
}else if("updateAuditDetail".equals(action)){  //保存(更新)
    UserPostDao userPostDao = new UserPostDao();
    String sData = request.getParameter("updateSets");
    List<KeshiAuditDetail> auditDetails = JSON.parseArray(sData, KeshiAuditDetail.class);  //字符串转集合
    boolean done = userPostDao.updateKeshiAuditDetails(auditDetails);
    String str=null;
    if(done){
        str="{success:true}";
    }else{
        str="{success:false}";
    }
    response.setContentType("text/html;charset=UTF-8");
    out=response.getWriter();
    out.print(str);     
    out.close();
    return;
}else if("deleteAuditDetails".equals(action)){   //删除
    String ids = request.getParameter("auditIds");
    UserPostDao userPostDao = new UserPostDao();
    boolean done = userPostDao.deleteAllKeshiAuditDetails(ids);
    String str =null;
    if(done){
        str="{success:true}";
    }else{
        str="{success:false}";
    }
    response.setContentType("text/html;charset=UTF-8");
    out=response.getWriter();
    out.print(str);     
    out.close();
    return;
}

注意:

1.用FastJsontoJSONString(obj/list);方法可以将对象或集合转化为相应的Json字符串

 

Dao方法获取数据的方式不同将导致转化的数据不同:

(1).普通集合:——错误方式

List list = query.list();
//获取到的是一堆Object数组的集合,Object数组没有属性——即没有键值对,所以转化的json字符串为非键值对格式的错误Json格式的字符串

转化的Json数据为:

[{0,"01",0,0,1,"企业科",0},{0,"qyk1",0,1,2,"企业科一号用户","01",0}]

 

(2).指定对象的集合:——正确方式

List<KeshiAuditDetail> auditDetails = query.addEntity(KeshiAuditDetail.class).list();

转化的Json数据为:

[
  {
    "autoid": 0,
    "bm": "01",
    "expand": 0,
    "isLeaf": 0,
    "level": 1,
    "mc": "企业科",
    "selected": 0
  },
  {
    "autoid": 0,
    "bm": "qyk1",
    "expand": 0,
    "isLeaf": 1,
    "level": 2,
    "mc": "企业科一号用户",
    "pid": "01",
    "selected": 0
  }
]

 
2.用FastJsonJSON.parse(jsonStr);方法可将Json字符串转化为对象
3.用FastJsonJSON.parseArray(jsonStr, T.class);方法可将Json字符串转化为指定类的集合

 

五.树节点数据的获取和解析:

1.用于从数据库获取分级数据的实体类:

/**
 * 用于从数据库获取分级数据,
 * 并作为等待解析的树节点数据的实体类
 */
public class SimpleBean {
    private String bm;      //id
    private String mc;      //text
    private String pid;     //关联的父节点ID
    private String href;
    private int level;      //节点所在层次;
    private int isLeaf;     //节点是否是叶子节点;
    private int selected;   //节点是否被选择;
    private String target;  //链接打开的位置
    private int expand;     //描述树节点时,表示是否展开
    private long autoid;
    ......
    ...
    ..
}

 

2.获取并解析树节点数据的Servlet:

if("getKeshiUsersByGrade".equals(action)){//按级别
    String jsonStr="";
    TreeDao tdao=new TreeDao();
    UserPostDao userPostDao = new UserPostDao();
    String did = request.getParameter("did")==null?"0":request.getParameter("did");
    //分级加载参数pid和loadAll的设置:
    String pid=request.getParameter("pid")==null?"":request.getParameter("pid");
    if(pid!=null&&(pid.startsWith("tree-root")||pid.startsWith("p-tree-root"))){
        pid="";//首次加载时,从根目录加载,pid为根节点AsyncTreeNode的id!
    }
    String sloadAll=request.getParameter("loadAll");
    int loadAll = 1;//loadAll:1:一次性全部加载,0:分级加载(点击树目录时加载)
    if (sloadAll != null && !sloadAll.equals("")) {
        loadAll=Integer.parseInt(sloadAll);
    }
    //获取数据并转化为树的格式的json数据:
    if ("".equals(pid) ) {
        List items = userPostDao.getKeshiUsersByGrade(did, pid, loadAll);
        //JSON.toJSONString(items);  转化后的是普通的Json格式数据,而非树所规定的Json格式
        jsonStr=tdao.getTreeNodesOfJson(items,loadAll,pid);
    }
    response.setContentType("text/json;charset=UTF-8");
    out=response.getWriter();
    out.print(jsonStr);     
    out.close();
    return;
}

 

3.Dao——获取分级数据:

/**
 * 获取科室用户制度树,按级别分类
 * @param pid
 * @param loadAll
 * @return
 */
public List getKeshiUsersByGrade(String did,String pid,int loadAll){
    List nodes=null;
    Session session = null;
    try{
        session =HibernateUtil.getSession();
        session.beginTransaction(); 
        StringBuffer treeSql = new StringBuffer("select * from(select bm,mc,pid,isleaf,level from(");
        treeSql.append(" select sdid as bm,sdname as mc, null as pid, 0 as isleaf from sub_department where pdid = ");
        treeSql.append(did);    
        treeSql.append(" union select u.userid as bm, u.name as mc, k.sdid as pid, 1 as isleaf from users u join user_keshi k on u.userid = k.userid");
        treeSql.append(" )connect by prior bm=pid start with pid is null )");
        if(loadAll==0){//分级加载
            if (pid == null||"".equals(pid))
                treeSql.append(" WHERE PID IS NULL ");
            else
                treeSql.append(" WHERE PID='").append(pid).append("'");
        }
        nodes = session.createSQLQuery(treeSql.toString())
        .addScalar("bm")
        .addScalar("pid")
        .addScalar("mc")
        .addScalar("isLeaf",Hibernate.INTEGER)
        .addScalar("level",Hibernate.INTEGER)
        .setResultTransformer(Transformers.aliasToBean(SimpleBean.class)).list();
        //此处直接用query.addEntity(SimpleBean.class);应该亦可,未验证
        session.getTransaction().commit();  
    }catch(Throwable e){
        log.error(e.toString());
        HibernateUtil.endSession(session);
    }finally{
        HibernateUtil.endSession(session);
    }
    return nodes;
}

注意:
获取分级数据时,要对获取到的数据的值的格式进行规范。

 

4.解析树节点数据的工具类:

import java.util.List;
import java.util.Map;
import org.json.JSONArray;
import org.json.JSONObject;
import com.huaxia.entity.SimpleBean;

/**
 * 创建时间: 2014年12月26日 上午11:39:36
 * 类描述:
 */
public class ParseTreeUtil {
    
    /**
     * 树节点的解析
     * @param items     //需要解析的数据集合
     * @param loadAll   //分级加载/一次性加载
     * @param pid       //关联的父节点ID
     * @return
     * @throws Exception
     */
    public String getTreeNodesOfJson(List items,int loadAll,String pid)throws Exception {
        if(items==null)return "";
        JSONArray jItems=new JSONArray();
        try{
            if(loadAll==1){//一次载入,从顶级编码开始,递归的加入子节点
                for(int i=0;i<items.size();i++){
                    SimpleBean oi=(SimpleBean)items.get(i);
                    if(oi.getPid()==null||"".equals(oi.getPid())){
                        jItems.put(parseOptionItem(items,oi,null,0));
                        
                    }
                }
            }else{
                for(int i=0;i<items.size();i++){
                    SimpleBean oi=(SimpleBean)items.get(i);
                    JSONObject ji=new JSONObject();
                    ji.put("id", oi.getBm());
                    ji.put("pid", oi.getPid());
                    ji.put("text", oi.getMc());
                    ji.put("leaf", oi.getIsLeaf()==1);
                    ji.put("cls",oi.getIsLeaf()==1?"file":"folder");
                    ji.put("expanded", oi.getExpand()==1);
                    ji.put("autoid", oi.getAutoid());
                    jItems.put(ji);
                }
            }
        }catch(Exception e){
            throw new Exception("编码解析为JSON格式时发生错误:"+e.toString());
        }
        return jItems.toString();
    }
    
    
    private JSONObject parseOptionItem(List initItems,SimpleBean oi,Map mcids,int checkById)throws Exception{
        if(oi==null){
            return null;
        }
        JSONObject ji=new JSONObject();
        ji.put("id", oi.getBm());
        ji.put("pid", oi.getPid());
        ji.put("text", oi.getMc());
        ji.put("leaf", oi.getIsLeaf()==1);
        ji.put("cls",oi.getIsLeaf()==1?"file":"folder");
        ji.put("expanded", oi.getExpand()==1);
        ji.put("autoid", oi.getAutoid());
        if(mcids!=null){
            if(checkById==1){
                ji.put("checked", mcids.containsKey(String.valueOf(oi.getBm())));
            }else{
                ji.put("checked", mcids.containsKey(String.valueOf(oi.getAutoid())));
            }
        }
        
        //检查当前节点的子节点
        String nextPid=oi.getBm();
        JSONArray cArray=new JSONArray();
        for(int i=0;i<initItems.size();i++){
            SimpleBean item=(SimpleBean)initItems.get(i);
            if(item!=null&&nextPid.equals(item.getPid())){//找到子节点,分别递归形成子节点分支的集合。
                cArray.put(parseOptionItem(initItems,item,mcids,checkById));
            }
        }
        if(cArray.length()>0){
            ji.put("children", cArray);
        }
        return ji;
    }
}

 

Dao方法获取到的List转化为普通的JSON数据如下:

[
  {
    "autoid": 0,
    "bm": "01",
    "expand": 0,
    "isLeaf": 0,
    "level": 1,
    "mc": "企业科",
    "selected": 0
  },
  {
    "autoid": 0,
    "bm": "qyk1",
    "expand": 0,
    "isLeaf": 1,
    "level": 2,
    "mc": "企业科一号用户",
    "pid": "01",
    "selected": 0
  },
  {
    "autoid": 0,
    "bm": "qyk2",
    "expand": 0,
    "isLeaf": 1,
    "level": 2,
    "mc": "企业库二号用户",
    "pid": "01",
    "selected": 0
  },
  {
    "autoid": 0,
    "bm": "02",
    "expand": 0,
    "isLeaf": 0,
    "level": 1,
    "mc": "行财科",
    "selected": 0
  },
  {
    "autoid": 0,
    "bm": "xck1",
    "expand": 0,
    "isLeaf": 1,
    "level": 2,
    "mc": "行财科一号用户",
    "pid": "02",
    "selected": 0
  },
  {
    "autoid": 0,
    "bm": "xck2",
    "expand": 0,
    "isLeaf": 1,
    "level": 2,
    "mc": "行财科二号用户",
    "pid": "02",
    "selected": 0
  }
]

 

解析成树节点格式的JSON数据如下:

[
  {
    "id": "01",
    "text": "企业科",
    "cls": "folder",
    "children": [
      {
        "id": "qyk1",
        "text": "企业科一号用户",
        "cls": "file",
        "pid": "01",
        "leaf": true,
        "autoid": 0,
        "expanded": false
      },
      {
        "id": "qyk2",
        "text": "企业库二号用户",
        "cls": "file",
        "pid": "01",
        "leaf": true,
        "autoid": 0,
        "expanded": false
      }
    ],
    "leaf": false,
    "autoid": 0,
    "expanded": false
  }
]
  {
    "id": "02",
    "text": "行财科",
    "cls": "folder",
    "children": [
      {
        "id": "xck1",
        "text": "行财科一号用户",
        "cls": "file",
        "pid": "02",
        "leaf": true,
        "autoid": 0,
        "expanded": false
      },
      {
        "id": "xck2",
        "text": "行财科二号用户",
        "cls": "file",
        "pid": "02",
        "leaf": true,
        "autoid": 0,
        "expanded": false
      }
    ],
    "leaf": false,
    "autoid": 0,
    "expanded": false
  }
]

 

六.获取树节点分级数据的SQL语句的分析:
1.用户表数据:

 
2.科室表数据:

 
3.用户科室关联表数据:

 
4.按照树节点格式查询科室数据:
select sdid as bm, sdname as mc, null as pid, 0 as isleaf
  from sub_department
 where pdid = 1;

 
5.查询与科室关联的用户数据:
select u.userid as bm, u.name as mc, k.sdid as pid, 1 as isleaf
  from users u
  join user_keshi k
    on u.userid = k.userid;

 
6.查询科室用户分级数据:
select *
  from (select bm, mc, pid, isleaf, level
          from (select sdid as bm, sdname as mc, null as pid, 0 as isleaf
                  from sub_department
                 where pdid = 1
                union
                select u.userid as bm,
                       u.name   as mc,
                       k.sdid   as pid,
                       1        as isleaf
                  from users u
                  join user_keshi k
                    on u.userid = k.userid)
        connect by prior bm = pid
         start with pid is null);

  
图示:

 

 
 
 
 
 
 

 

 

 

 

 

 

 

  • 大小: 4.8 KB
  • 大小: 4.5 KB
  • 大小: 8 KB
  • 大小: 8.9 KB
  • 大小: 6.9 KB
  • 大小: 5.6 KB
  • 大小: 11.1 KB
  • 大小: 7.6 KB
  • 大小: 14.9 KB
  • 大小: 14.5 KB
  • 大小: 15.7 KB
  • 大小: 4.8 KB
  • 大小: 4.3 KB
  • 大小: 7.4 KB
  • 大小: 3.1 KB
  • 大小: 5 KB
  • 大小: 7.1 KB
  • 大小: 4.2 KB
  • 大小: 6.6 KB
  • 大小: 8.7 KB
  • 大小: 7.1 KB
分享到:
评论

相关推荐

    Extjs 各种总结和新实例

    本人对extjs 各种开发的亲身总结,包括多种列表、树、以及很多扩展功能

    extJs 2.1学习笔记

    1. ExtJs 结构树 2 2. 对ExtJs的态度 3 3. Ext.form概述 4 4. Ext.TabPanel篇 5 5. Function扩展篇 7 6. Ext.data.Store篇 10 7. Ext.data.JsonReader篇一 12 8. Ext.data.JsonReader篇二 15 9. Ext.data.HttpProxy...

    ExtJs学习笔记,共30讲

    1. ExtJs 结构树 2 2. 对ExtJs的态度 3 3. Ext.form概述 4 4. Ext.TabPanel篇 5 5. Function扩展篇 7 6. Ext.data.Store篇 10 7. Ext.data.JsonReader篇一 12 8. Ext.data.JsonReader篇二 15 9. Ext.data.HttpProxy...

    EXTJS总结.txt

    从DOM里面移除当前元素,并从缓存中删除。. Ext.fly('elId').remove(); // elId在缓存和dom里面都没有 40.removeNode 移除document的DOM节点。如果是body节点的话会被忽略。 Ext.removeNode(node); // 从dom...

    SSH+extjs+json动态树的构造(附详细步骤及源码)

    本文档是自己亲身实践的总结文档,包括构造ext动态树的js代码,action层,service层,dao层以及实体类的示例,思路很清晰。如还有疑问,可以留言。最后附上了一段增加树节点的示例。删除修改类同。

    Extjs中ComboBoxTree实现的下拉框树效果(自写)

    最近涉及到的一个项目中,需要实现ComboBoxTree的效果,首先,看看效果吧…… 在Extjs中是没有这种效果的,所以得自己写,在网络上看了看别人的资料,自己再总结了一下,修改了一下,代码如下: 代码如下: Ext.ux....

    Extjs表单中的通用组件

    在实践中总结的文档,适用于Ext的初学人群!

    GWT-ext 布局示例

    GWT-Ext 是基于 Google Web Toolkit(GWT)和 ExtJs 的功能强大的网页开发控件库。它非常适用于进行纯 Java 语言的富 Internet ...在对树的介绍中,我们将从树的同步和异步方式的初始化到树的 一些特性进行详细介绍。

    快意编程 EXT JS Web开发技术详解.pdf

    《快意编程:Ext JS Web开发技术详解》是笔者在多年项目开发过程中的经验总结,它通过丰富的实例由浅入深、循序渐进地介绍了目前采用Ext JS进行Web开发的使用方法,从而帮助软件设计人员快速掌握Ext JS开发技术的使用...

    Ext Js权威指南(.zip.001

    1.2.4 在javascript中使用json / 4 1.2.5 在.net中使用json / 8 1.2.6 在java中使用json / 12 1.2.7 更多有关json的信息 / 15 1.3 ext js 4概述 / 15 1.4 ext js的开发工具的获取、安装与配置介绍 / 18 1.4.1...

    GoodProject Maven Webapp.zip

    系统主要运用在:在系统中一些分页或者样式交互事件处理中使用到了(比如地址选择框) 前端用到了ajax AJAX即"Asynchronous Javascript And XML"(异步JavaScript和XML),是指一种创建交互式网页应用的网页开发技术。...

Global site tag (gtag.js) - Google Analytics