easyUI中树形菜单数据的加载

前言

这是在使用easyui的过程中遇到的问题。出错的原因还是自己粗心,最主要的是对easyui不熟悉,没能很好理解tree的加载方式。写下这篇文章来记录下,方便以后需要时查看。
补充:树形菜单和树形下拉框几乎一样。都是通过url属性加载数据。唯一的区别就是树形菜单是tree控件,而树形下拉框是combotree控件,用法一样。

问题及其解决

easyui的树形菜单的一个问题,如图:

理想的情况展开父节点时出现的应该是其子节点。但是现在不知道为什么,展开的节点还是父节点本身,一直展开,一直都是这个节点。

之所以会出现这个问题,主要还是对easyui不熟悉和不理解。

一开始,我的前端代码是这样的:

$('#wu-category-tree').tree({
    url:'/dept/getTree',
});

然后显示的结果是这样:

但是,展开a部门,出现的还是a部门。

虽然这里能把树形菜单初始化显示出来。但是其实对easyui的tree还是不理解。譬如上面写的前端代码,我并没有传递参数啊。

我的疑惑是,怎么让节点id作为url的参数传到后台啊。看了文档,没找到答案。

上网查了一下,看到这个代码:

$(function(){  
 $("#tree").tree({  
    method:"get",  
    url:"test/tree",//这里写用来调用的后台的方法             
    onBeforeExpand:function(node,param){  
        url:"test/tree?pid="+node.id;  
//在节点展开之前触发,这里将单击节点的id传到后台,就可以查出所有该节点的子节点,然后展示  
    }  
 });  
});  

试了一下,加上onBeforeExpand事件,发现还是不行。

又试了直接在浏览器的地址栏上发起请求:

http://localhost:8080/dept/getTree?parentId=31

发现是能返回正常的数据的:

[{"id":32,"text":"b部门","checked":false,"children":null,"state":"closed"},
{"id":33,"text":"c部门","checked":false,"children":null,"state":"closed"},
{"id":34,"text":"d部门","checked":false,"children":null,"state":"open"}]

根据以往经验,每次在浏览器地址栏访问正常而在通过网站访问却不行,都是controller层出现问题!先看看发起请求时前台传到后台的参数:

传的是id字段!!!

突然记起控制台sql语句说我传了两个参数,并且查询到的结果是一条。当时没多留意,只是觉得很奇怪,应该是只传了一个parentId才对啊。

这时才想明白问题是出在controller方法:

@RequestMapping(value = "/getTree")
@ResponseBody
public List getTree(Dept dept){
    logger.info("前台传来的参数id为"+dept.getId());
    if(dept.getParentId()==null)
        dept.setParentId(0);
    return deptService.getTree(dept);
}

controller方法这里,前台传来的是id字段,我傻了,理所当然的认为传来的是parentId字段。结果我对parentId字段进行验证,如果为null,则设置为0。从而,导致在展开的时候传递到后台的id是31,而parentId为0。因此查询出来的一直都是a部门。

找到问题后,就很好改了:

@RequestMapping(value = "/getTree")
@ResponseBody
public List getTree(Integer id){
    Dept dept = new Dept();
    if(id==null)
        dept.setParentId(0);
    else
        dept.setParentId(id);
    return deptService.getTree(dept);
}

收获

树形菜单的加载:

$('#wu-category-tree').tree({
    url:'/dept/getTree',
});

easyui很强大,通过这一句,只要后台传来的数据正确,就能加载自动加载出树形菜单。

我一开始就是很疑惑,我要怎么传id啊。我要怎样在展开时再次发起请求。看了文档,没找到答案。原来,在展开父节点时,会自动将该节点的id值作为参数发起请求,获取到数据后,自动加载出子树菜单。

代码记录

serviceImpl

(核心)serviceImpl层,实现数据的封装:

public List getTree(Dept dept){
    List<TreeDTO> dtoList = new ArrayList<TreeDTO>();//用来存放子节点
    List<Dept> deptList = deptDao.query(dept,null,null);//dept对象的有效数据是parentId,即query方法实现的是找出指定parentId的记录
    if(deptList==null || deptList.size()==0)
        return null;
    for(Dept temp:deptList){//处理每个子节点
        TreeDTO<Dept> td = new TreeDTO<Dept>(temp.getId(),temp.getName());//每个子节点都封装成dto对象
        Dept deptWithParentId = new Dept();//作为query方法的参数
        deptWithParentId.setParentId(temp.getId());//该参数只设置了parentId属性
        List<Dept> childrenList = deptDao.query(deptWithParentId,null,null);//调用该方法,为的是查看该节点是否有子节点
        if(childrenList.size()>0)
            td.setState("closed");//td.setState("colsed");//一开始写错了,导致无法展开和折叠
        else
            td.setState("open");//叶子节点,得将status属性设置为open,表示其已经是展开了的
        dtoList.add(td);//最后把子节点放到list中
    }
    return dtoList;//返回list
}

query方法

(我使用的是MyBatis)
Dao接口方法:

/**
 * 根据参数进行查询,得到相关部门的列表
 * @param dept
 * @param offset
 * @param limit
 * @return
 */
List<Dept> query(@Param("dept") Dept dept,@Param("offset") Integer offset,@Param("limit") Integer limit);

mapper.xml:

<select id="query" resultType="Dept">
    SELECT * FROM dept_inf
    <where>
        1=1
        <if test="dept.id != null">
            AND id = #{dept.id}
        </if>
        <if test="dept.name != null">
            AND name = #{dept.name}
        </if>
        <if test="dept.remark != null">
            AND remark = #{dept.remark}
        </if>
        <if test="dept.parentId != null">
            AND parent_id = #{dept.parentId}
        </if>
    </where>
    <if test="offset !=null">
        limit #{offset},#{limit}
    </if>
</select>

Bean

public class Dept implements Serializable{
    private Integer id;
    private String name;//部门名称
    private String remark;//详细描述
    private Integer parentId;//直属上级部门
    //省略getter方法和setter方法
}

TreeDTO

(之所以要有这个类,是为了配了easyui的使用,easyui要求你传回这种格式的数据)

public class TreeDTO<E> {//使用泛型是因为职位类也需要用到树形结果,通过泛型就能通用了
    private int id;
    private String text;
    private boolean checked;
    private List<TreeDTO> children;
    private String state;
    //省略getter方法和setter方法
}

controller方法

@RequestMapping(value = "/getTree")
@ResponseBody
public List getTree(Integer id){
    Dept dept = new Dept();
    if(id==null)    //是判断id字段!传来的id字段要作为parentId条件来查询
        dept.setParentId(0);
    else
        dept.setParentId(id);
    return deptService.getTree(dept);
}

前端代码

<div data-options="region:'west',border:true,split:true," title="部门选择" style="width:200px; padding:5px;">
    <ul id="wu-category-tree" class="easyui-tree"></ul>
</div>
$('#wu-category-tree').tree({
    url:'/dept/getTree',
    animate:true,
});

效果

easyui框架的参考文档:

http://www.jeasyui.net/tutorial/

猜你喜欢

转载自blog.csdn.net/weixin_30531261/article/details/79415188
今日推荐