`

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 4 树形表格组件使用示例

    总结来说,EXTJS 4的树形表格组件是一个强大且灵活的工具,它集成了树状结构和表格的特性,为开发者提供了一种高效展示和操作层次数据的方式。无论是在桌面端还是移动端的应用开发中,EXTJS 4的TreeGrid都是一个值得...

    EXTJS动态树支持checkbox 全选

    总结来说,EXTJS动态树支持checkbox全选是一个结合了EXTJS TreePanel组件、数据模型、事件处理和异步加载技术的功能实现,旨在提供用户友好的多选操作。通过这个功能,开发者可以构建出更加交互性强、功能丰富的Web...

    Extjs 无限树菜单 后台拼接json

    总结来说,"Extjs 无限树菜单 后台拼接json"涉及到的技术点包括:ExtJS的树形组件使用、后台动态生成JSON、无限滚动加载策略、以及前端和后端的异步通信。通过这样的方式,我们可以构建出动态、可扩展且高效的树形...

    Extjs4动态树的实现

    总结来说,这个例子展示了如何使用ExtJS4和Java实现一个动态树结构。前端通过TreeStore从后端动态获取数据,当用户点击树节点时,会触发新的数据请求。后端根据请求参数返回JSON数据,更新树结构。这种动态加载的...

    EXTJS实例 EXTJS树,可以编辑的EXTJS,EXTJS3.0

    页面组件示例中心可能包含了一系列EXTJS3.0的组件演示,包括树形组件的实例,你可以通过这些实例学习如何在实际项目中使用和定制EXTJS3.0的树组件,提升你的前端开发能力。 总结来说,EXTJS3.0的树形组件提供了一种...

    extjs动态树struts请求数据

    总结以上,ExtJS动态树与Struts的结合使用,需要熟练掌握ExtJS TreePanel的配置,JSON数据的构造和解析,以及Struts2的Action和Result机制。通过Ajax请求,前端可以动态获取和更新树形数据,实现交互式用户界面。

    ExtJs树例子

    总结来说,"ExtJs树例子"涵盖了ExtJS的TreePanel组件的使用,包括数据源配置、节点模型、用户交互、扩展功能等方面的知识。通过学习和实践这个例子,开发者能够熟练掌握在Web应用中创建和管理树形结构的方法。

    Extjs折叠布局中添加树

    通过这个示例,我们可以了解到如何在ExtJS的折叠布局中集成树形结构,以及如何从服务器动态加载数据来构建这个树。这在实现具有层次结构的导航菜单或信息分类时非常有用。同时,我们也学习到了如何创建和配置不同的...

    使用ExtJs构建树形菜单功能

    ### 使用ExtJs构建树形菜单功能详解 #### 一、引言 在现代Web应用程序开发中,树形菜单是一项常用且重要的功能。它能够帮助用户更直观地理解数据层次关系,尤其是在展示组织架构、文件系统或者任何有层级结构的...

    Extjs自定义组件-下拉树

    本文将围绕“Extjs自定义组件—下拉树”这一主题,详细阐述其实现原理、使用方法以及核心代码分析。 #### 一、理解下拉树组件 下拉树组件结合了下拉框(ComboBox)与树形结构(Tree),旨在提供一种直观、高效的...

    extjs 总结

    在EXTJS中,TreePanel是用于展示树形数据结构的组件,广泛应用于组织层次结构信息,如文件系统、组织架构等。 **EXTJS TreePanel 知识点** 1. **配置项** - `root`: TreePanel 的根节点,通常是整个树的起点。 -...

    extjs 常用控件的使用 table layout

    EXTJS 是一款强大的...掌握EXTJS的控件使用和Table Layout,可以帮助开发者高效地创建出专业且用户友好的前端应用。在实际开发过程中,应根据具体需求灵活运用EXTJS的组件和布局,以达到最佳的界面设计和交互效果。

    SSH+extjs+json动态树的搜索

    总结起来,这篇文章介绍了一种使用SSH、ExtJS和JSON实现动态树搜索的高效方法。它避免了全树展开的低效,通过路径查找提高了性能,同时通过ExtJS的事件处理和前端-后端通信实现了良好的用户体验。

    ExtJS下拉列表树控件

    接下来,我们关注如何在GridPanel中使用编辑器(Editor)结合下拉列表树控件。编辑器GridPanel(EditorGridPanel)允许用户在单元格内直接编辑数据,这对于数据输入非常方便。在定义GridPanel的列模型(column model...

    jsp+access+extjs动态树实例

    总结起来,"jsp+access+extjs动态树实例"是一个综合性的Web开发案例,它结合了服务器端的JSP处理、数据库操作以及客户端的动态展示技术,展示了如何利用现有工具和技术实现一个功能丰富的交互式动态树视图。...

    EXTJS开发总结.pdf

    EXTJS是一种专为Rich Internet Applications (RIA)设计的前端JavaScript框架,它的主要定位与Prototype、jQuery...在实际项目中,结合良好的代码管理和调试技巧,EXTJS能够帮助企业构建出高效、用户体验优秀的Web应用。

    extjs2.2 oozie可以使用的 1积分

    ExtJS和Oozie是两个在IT行业中广泛使用的开源工具,它们在大数据处理和Web应用程序开发方面发挥着重要作用。在本篇文章中,我们将深入探讨这两个技术以及它们之间的结合。 **ExtJS 2.2** ExtJS是一个基于JavaScript...

    ExtJS4.2 tree 级联选择

    总结一下,"ExtJS4.2 tree 级联选择"是通过ExtJS的TreePanel组件实现的,利用了`selModel`的级联选择功能,配合`check-tree.js`中的逻辑代码,读取`check-nodes.json`作为数据源,构建了一个具有交互式的树形选择器...

    EXTJS动态树的实现

    EXTJS动态树是一种基于JavaScript的UI组件,用于在网页中构建可交互的树形结构数据展示。EXTJS是一个强大的前端框架,提供了丰富的组件库,包括表格、表单、树、图表等多种元素,使得开发者能够创建出功能丰富且用户...

Global site tag (gtag.js) - Google Analytics