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,
});