这几天做项目过程中,在项目的后台使用的是ligerUI,遇到了不少的问题,其中在tree上磕碰最多,在不断的尝试下,写了好几种不同的实现方式,在此总结一下,方便日后自己使用时可以信手拈来,同时也希望可以帮助其他的遇到和我类似问题的哥们儿。
ligerTree有三种不同的实现方式。关于ligerTree的API我就不多说了,网上一大堆,关键是如何使用。
第一种:点击加载子节点,一级一级显示。这个方式核心思想是:递归。
页面js代码:
//加载树
$("#maintree").ligerTree( {
url : 'viewtree?'+$.param( {
typeid:'1',
parentid : '-1'
}),
checkbox :false,
slide : false,
isleaf : false,
onBeforeExpand : onBeforeExpand,
onClick : function(node) {
if(node!=null && node.data!=null){
nodeid = node.data.nodeid;
if(nodeid != -1&&node.data.typeid==-1) {
gridManager.setOptions( {
parms : [{
name : 'organid',
value : nodeid
}]
});
gridManager.loadData(true);
}
}
}
});
//展开前事件,节点展开之前加载子节点的内容
function onBeforeExpand(node) {
if (node.data.children && node.data.children.length ==0&&node.data.typeid!=-1) {
treeManager.loadData(node.target,
'viewtree?' + $.param( {
parentid : node.data.nodeid,
typeid:node.data.typeid
}));
}
}
控制层的方法:
/**
* 加载组织管理树
* @param request
* @param response
* @param writer
* @return
*/
@RequestMapping("/viewtree")
public String viewTree1(HttpServletRequest request,HttpServletResponse response,PrintWriter writer) {
JSONObject jsonObj = new JSONObject();
String parentid=request.getParameter("parentid");
String typeid=request.getParameter("typeid");
String treeJSON = "";
try{
if(typeid.equals("2")){ //盟市教研室
List<TbOrganization> menuList=tbOrganizationService.getAllMenus(parentid);
if(menuList!=null&&menuList.size()>0){
for(TbOrganization menu:menuList){
jsonObj.put("text",menu.getName());
jsonObj.put("nodeid",menu.getOrganid());
jsonObj.put("parentid",menu.getParentid());
jsonObj.put("type", menu.getType());
jsonObj.put("isexpand", "false");
jsonObj.put("typeid",3);
jsonObj.put("children", "[]");
treeJSON += jsonObj.toString() + ",";
}
}
}else if(typeid.equals("3")) //加载旗县教研室
{
List<TbOrganization> menuList=tbOrganizationService.getAllMenus(parentid);
if(menuList!=null&&menuList.size()>0){
for(TbOrganization menu:menuList){
jsonObj.put("text",menu.getName());
jsonObj.put("nodeid",menu.getOrganid());
jsonObj.put("parentid",menu.getParentid());
jsonObj.put("type", menu.getType());
jsonObj.put("isexpand", "false");
jsonObj.put("typeid",4);
treeJSON += jsonObj.toString() + ",";
}
}
}else if(typeid.equals("4")) //加载学校
{
List<TbOrganization> menuList=tbOrganizationService.getAllMenus(parentid);
if(menuList!=null&&menuList.size()>0){
for(TbOrganization menu:menuList){
jsonObj.put("text",menu.getName());
jsonObj.put("nodeid",menu.getOrganid());
jsonObj.put("parentid",menu.getParentid());
jsonObj.put("type", menu.getType());
jsonObj.put("isexpand", "false");
jsonObj.put("typeid",-1);
//jsonObj.put("children", "[]");
treeJSON += jsonObj.toString() + ",";
}
}
}else //加载教育厅教研室
{
List<TbOrganization> menuList=tbOrganizationService.getAllMenus(parentid);
if(menuList!=null&&menuList.size()>0){
for(TbOrganization menu:menuList){
jsonObj.put("text",menu.getName());
jsonObj.put("nodeid",menu.getOrganid());
jsonObj.put("parentid",menu.getParentid());
jsonObj.put("type", menu.getType());
jsonObj.put("isexpand", "false");
jsonObj.put("typeid",2);
jsonObj.put("children", "[]");
treeJSON += jsonObj.toString() + ",";
}
}
}
}catch(Exception ex){
ex.printStackTrace();
}
if (!treeJSON.equals("")){
//去掉了最后的,
treeJSON = treeJSON.substring(0, treeJSON.lastIndexOf(","));
}
treeJSON = "[" + treeJSON + "]";
if (treeJSON.equals("[{}]")){
treeJSON = "[]";
}
writer.print(treeJSON);
return null;
}
services层、Mapper层代码我都不粘贴了,很简单啦。下面是几张图片可以帮助理解:
第二种方式:一次性加载出来整个tree(含有树的右键菜单). 这种方法核心是:关联集合
页面js :
var gridManager = null;
var treeManager =null;
var contextmenuManager=null;
$(function ()
{
var layout = $("#layout").ligerLayout( {
leftWidth : 200
});
//加载树的右键菜单
contextmenuManager = $.ligerMenu({ top: 100, left: 100, width: 120,items:
[
{ id: 'addmenu',text: '新建子菜单', click: cmitemclick },
{ line: true },
{ id: 'modifymenu',text: '修改菜单', click: cmitemclick },
{ id: 'deletemenu',text: '删除菜单', click: cmitemclick }
]
});
//加载菜单树
$("#maintree").ligerTree({
url: '${ctx}/resource/viewtree',
checkbox : false,
slide : false,
isleaf : false,
onClick : function(node) {
if(node!=null&&node.data!=null){
gridManager.setOptions( {
parms : [{
name : 'parentid',
value : node.data.nodeid
}]
});
gridManager.loadData(true);
}
},
onContextmenu: function (node, e){
selectedNode=node;
if(node.data.parentid==-1){
contextmenuManager.setEnabled('addmenu');
contextmenuManager.setDisabled('modifymenu');
contextmenuManager.setDisabled('deletemenu');
}else{
contextmenuManager.setDisabled('addmenu');
contextmenuManager.setEnabled('modifymenu');
contextmenuManager.setEnabled('deletemenu');
}
contextmenuManager.show({ top: e.pageY, left: e.pageX });
return false;
}
});
treeManager = $("#maintree").ligerGetTreeManager();
});
控制层的方法:
/*
* 加载树(多次查询)
*/
@RequestMapping("/viewtree")
public String viewTree(HttpServletRequest request,HttpServletResponse response,PrintWriter writer) {
JSONArray menuArr=new JSONArray();
try{
//获取这个集合的时候在sql语句中需要一个关联。getAllMenus()是查的一级节点内容,同时关联查出二级节点的内容。sql语句的关联我写在下面啦
List<TbOrganization> menuList=tbOrganizationService.getAllMenus();
if(menuList!=null){
for(TbOrganization menu:menuList){
List<TbOrganization> childrenList=menu.getChildren();
JSONObject nodeJson=new JSONObject();
nodeJson.put("text",menu.getName());
nodeJson.put("nodeid",menu.getOrganid());
nodeJson.put("parentid",menu.getParentid());
nodeJson.put("type", menu.getType());
if(childrenList!=null&&childrenList.size()>0){
JSONArray childMenuArr=new JSONArray();
for(TbOrganization childMenu: childrenList){
JSONObject childNodeJson=new JSONObject();
childNodeJson.put("text",childMenu.getName());
childNodeJson.put("nodeid",childMenu.getOrganid());
childNodeJson.put("parentid",childMenu.getParentid());
childNodeJson.put("type", menu.getType());
if(childMenu.getOrganid()!=null)
{
JSONArray GrandchildMA=new JSONArray();
List<TbOrganization> QXList=tbOrganizationService.getOrganizationListByParentId(childMenu.getOrganid());
for(TbOrganization GrandchildMenu: QXList)
{
JSONObject GrandchildNodeJson=new JSONObject();
GrandchildNodeJson.put("text",GrandchildMenu.getName());
GrandchildNodeJson.put("nodeid",GrandchildMenu.getOrganid());
GrandchildNodeJson.put("parentid",GrandchildMenu.getParentid());
GrandchildNodeJson.put("type", GrandchildMenu.getType());
GrandchildMA.add(GrandchildNodeJson);
}
childNodeJson.put("children", GrandchildMA);
}
childMenuArr.add(childNodeJson);
}
nodeJson.put("children", childMenuArr);
}
menuArr.add(nodeJson);
}
}
}catch(Exception ex){
ex.printStackTrace();
}
writer.println(menuArr.toJSONString());
return null;
}
使用第二种方式的需要注意以下几点:
1.在你的实体层需要有一个集合:private List<TbOrganization> children = new ArrayList<TbOrganization>(); //关联子节点
2.sql语句:
<!--加载树 -->
<select id="getAllMenus" parameterType="Integer" resultType="TbOrganization">
select
<include refid="Base_Column_List" /> //需要显示的字段
from tb_organization
<if test="type==0" >
where type=#{type}
</if>
</select>
<sql id="Base_Column_List" >
organid, name, parentid,type, remark
</sql>
// 关联需要加载的子节点
<resultMap id="BaseResultMap" type="TbOrganization" >
<id column="organid" property="organid" jdbcType="VARCHAR" />
<result column="type" property="type" jdbcType="INTEGER" />
<collection property="children" select="selectOrganizationChildren" column="organid" ofType="TbOrganization"></collection>
</resultMap>
//collection中的属性select的值和下面查询sql语句中的id的值相同
<select id="selectOrganizationChildren" parameterType="String" resultType="TbOrganization">
select
<include refid="Base_Column_List" />
from tb_organization
where parentid= #{organid}
</select>
第二种方式的缺点:对于3级以下节点可以选择使用,超过3级就不推荐使用。控制层中循环查询可能就会很影响效率。
第三种方式: 一次性加载出来整个tree(不含有树的右键菜单) 推荐使用第三种方式:简单 方便 快捷,我就是使用的这种方式。这种方式需要一次性查出所有的数据。
js页面代码:
var data1 = [];
$.post("viewtree",function(data){
for(var i=0;i<data.length;i++)
{
//tree的数据源
data1.push({ id:data[i].nodeid, pid:data[i].parentid,type:data[i].type, text:data[i].text });
}
treeManager=$("#maintree").ligerTree({
data:data1,
checkbox:false,
idFieldName :'id',
parentIDFieldName :'pid',
onclick:function(node)
{
if(node!=null&&node.data!=null)
{
gridManager.setOptions({
parms : [{
name : 'parentid',
value : node.data.id
}]
});
formdata(node.data.id);
gridManager.loadData(true);
}
}
});
},'json');
控制层:
@RequestMapping("/viewtree")
public String viewTree(HttpServletRequest request,HttpServletResponse response,PrintWriter writer) {
String type=request.getParameter("type");
String treeJSON = "";
JSONObject jsonObj = new JSONObject();
try{
List<TbOrganization> menuList=tbOrganizationService.getAllMenus(Integer.parseInt(type));
if(menuList!=null&&menuList.size()>0){
for(TbOrganization menu:menuList){
jsonObj.put("text",menu.getName());
jsonObj.put("nodeid",menu.getOrganid());
jsonObj.put("parentid",menu.getParentid());
jsonObj.put("type", menu.getType()+"");
treeJSON += jsonObj.toString() + ",";
}
}
}catch(Exception ex){
ex.printStackTrace();
}
if (!treeJSON.equals("")){
//去掉了最后的,
treeJSON = treeJSON.substring(0, treeJSON.lastIndexOf(","));
}
treeJSON = "[" + treeJSON + "]";
if (treeJSON.equals("[{}]")){
treeJSON = "[]";
}
writer.print(treeJSON);
return null;
}
这三种方式我都实现过,最后选择的是第三种。
over。