首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

EasyUI Combobox 實現靜態數據兩級聯動完整實戰

     編輯:Java 相關知識

前言

下拉框聯動是表單開發常見需求。本文基於 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);

二、後端實現

1. 實體類

public class Categorytbl {
    private Integer categoryid;
    private String categoryName;
    private Integer parentid;
    private Integer sortOrder;
    // getter/setter
}

2. Service 介面與實現

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

3. Action:返回 JSON 陣列

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
}

4. Struts 配置

<action name="itemManage!categorytbl" class="itemManageAction" method="categorytbl">
    <result type="json"/>
</action>
<action name="itemManage!leibie" class="itemManageAction" method="leibie">
    <result type="json"/>
</action>

三、前端實現:核心邏輯在 onHidePanel 事件

<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>

四、JSP 頁面完整結構

<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 onSelectonSelect 在鍵盤選擇、程式化 setValue 也會觸發;onHidePanel 僅在面板關閉觸發,更適合聯動場景
loadData vs urlurl 適合初始化;loadData 適合動態替換數據源,無需重新請求
valueField/textField必須與後端 JSON 字段名一致(categoryid/categoryName)
editable: false禁止手動輸入,強制選擇列表值
panelHeight: 'auto'面板高度自適應,避免滾動條或截斷

六、進階優化建議

  • 緩存頂級欄目:頂級欄目變動極少,可用 Spring Cache 或應用啟動時載入至 Application 域,減少 DB 查詢。
  • 防抖處理:快速切換欄目時,取消上一個未完成的 AJAX 請求(xhr.abort())。
  • 載入狀態:onLoadSuccess 回調中顯示提示,onLoadError 處理異常。
  • 多級聯動擴展:同理可擴展至三級、四級,建議封裝為通用聯動組件。
  • 資料權限:後端查詢時根據當前用戶角色過濾可見分類。

七、常見問題排查

  • 子分類不顯示:檢查 valueField/textField 是否與 JSON 字段名一致;瀏覽器 Network 面板確認 AJAX 返回數據格式。
  • 重複請求:cache: false 會每次請求,若數據靜態可改為 true 並手動清理緩存。
  • 中文亂碼:確保 JSP pageEncoding="UTF-8"、Action response.setCharacterEncoding("UTF-8")、資料庫字符集一致。

八、總結

EasyUI Combobox 聯動核心在於:父級 onHidePanel 事件 → 獲取值 → AJAX 請求子級數據 → loadData 重載子級 Combobox。掌握此模式,配合後端自關聯表設計,可快速實現任意層級下拉框聯動。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved