下拉框聯動是表單開發常見需求。本文基於 SSH(Struts2 + Spring + Hibernate)架構,詳細演示如何使用 EasyUI Combobox 實現「欄目 → 種類」兩級靜態數據聯動,涵蓋資料庫設計、後端查詢、前端事件綁定全流程。
CREATE TABLE CATEGORY_TBL (
CATEGORY_ID NUMBER(10) PRIMARY KEY,
CATEGORY_NAME VARCHAR2(100) NOT NULL,
PARENT_ID NUMBER(10) DEFAULT 0, -- 0 表示頂級欄目
SORT_ORDER NUMBER(5) DEFAULT 0
);
-- 測試數據
INSERT INTO CATEGORY_TBL VALUES (1, '法律法規', 0, 1); -- 頂級欄目
INSERT INTO CATEGORY_TBL VALUES (2, '中國公民出國', 1, 1); -- 子分類
INSERT INTO CATEGORY_TBL VALUES (3, '邊境居民往來港澳', 1, 2);
INSERT INTO CATEGORY_TBL VALUES (4, '財稅政策', 0, 2);
INSERT INTO CATEGORY_TBL VALUES (5, '個稅改革', 4, 1);
public class Categorytbl {
private Integer categoryid;
private String categoryName;
private Integer parentid;
private Integer sortOrder;
// getter/setter
}
public interface ItemService {
List<Categorytbl> queryLanMu() throws Exception; // 查詢頂級欄目
List<Categorytbl> queryLeiBie(String parentId) throws Exception; // 查詢子分類
}
public class ItemServiceImpl implements ItemService {
private SessionFactory sessionFactory;
public List<Categorytbl> queryLanMu() {
Criteria criteria = sessionFactory.getCurrentSession()
.createCriteria(Categorytbl.class);
criteria.add(Restrictions.eq("parentid", 0));
criteria.addOrder(Order.asc("categoryid"));
return criteria.list();
}
public List<Categorytbl> queryLeiBie(String parentId) {
Criteria criteria = sessionFactory.getCurrentSession()
.createCriteria(Categorytbl.class);
criteria.add(Restrictions.eq("parentid", Integer.parseInt(parentId)));
criteria.addOrder(Order.asc("categoryid"));
return criteria.list();
}
}
public class ItemManageAction {
private ItemService itemService;
private String lanmuid; // 前端傳遞的父級 ID
public String categorytbl() throws IOException {
List<Categorytbl> list = itemService.queryLanMu();
toJsonArray(list);
return null;
}
public String leibie() throws IOException {
List<Categorytbl> list = itemService.queryLeiBie(lanmuid);
toJsonArray(list);
return null;
}
private void toJsonArray(List<Categorytbl> list) throws IOException {
HttpServletResponse response = ServletActionContext.getResponse();
response.setCharacterEncoding("UTF-8");
response.setContentType("application/json");
JSONArray json = JSONArray.fromObject(list); // net.sf.json
response.getWriter().write(json.toString());
}
// getter/setter
}
<action name="itemManage!categorytbl" class="itemManageAction" method="categorytbl">
<result type="json"/>
</action>
<action name="itemManage!leibie" class="itemManageAction" method="leibie">
<result type="json"/>
</action>
<script type="text/javascript">
$(function() {
// 欄目下拉框:初始化載入頂級欄目
$('#lanmu').combobox({
url: 'itemManage!categorytbl',
editable: false,
cache: false,
panelHeight: 'auto',
valueField: 'categoryid',
textField: 'categoryName',
// 關鍵:面板隱藏時觸發(用戶選擇後)
onHidePanel: function() {
// 1. 清空子分類選擇
$("#leibie").combobox("setValue", '');
// 2. 獲取當前選中的欄目 ID
var lanmuid = $('#lanmu').combobox('getValue');
if (!lanmuid) return;
// 3. AJAX 請求子分類數據
$.ajax({
type: "POST",
url: "itemManage!leibie?lanmuid=" + lanmuid,
cache: false,
dataType: "json",
success: function(data) {
// 4. 載入子分類數據
$("#leibie").combobox("loadData", data);
}
});
}
});
// 種類下拉框:初始為空,動態載入
$('#leibie').combobox({
editable: false,
cache: false,
panelHeight: 'auto',
valueField: 'categoryid',
textField: 'categoryName'
});
});
</script>
<body>
<div id="tb">
<form>
<span>所屬欄目:</span>
<select id="lanmu" class="lanmu"></select>
<span>種類:</span>
<select id="leibie" class="leibie"></select>
</form>
</div>
</body>
| 技術點 | 說明 |
|---|---|
| onHidePanel vs onSelect | onSelect 在鍵盤選擇、程式化 setValue 也會觸發;onHidePanel 僅在面板關閉觸發,更適合聯動場景 |
| loadData vs url | url 適合初始化;loadData 適合動態替換數據源,無需重新請求 |
| valueField/textField | 必須與後端 JSON 字段名一致(categoryid/categoryName) |
| editable: false | 禁止手動輸入,強制選擇列表值 |
| panelHeight: 'auto' | 面板高度自適應,避免滾動條或截斷 |
xhr.abort())。onLoadSuccess 回調中顯示提示,onLoadError 處理異常。valueField/textField 是否與 JSON 字段名一致;瀏覽器 Network 面板確認 AJAX 返回數據格式。cache: false 會每次請求,若數據靜態可改為 true 並手動清理緩存。pageEncoding="UTF-8"、Action response.setCharacterEncoding("UTF-8")、資料庫字符集一致。EasyUI Combobox 聯動核心在於:父級 onHidePanel 事件 → 獲取值 → AJAX 請求子級數據 → loadData 重載子級 Combobox。掌握此模式,配合後端自關聯表設計,可快速實現任意層級下拉框聯動。