1. 程式人生 > >easyUI中樹形選單資料的載入

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框架的參考文件: