首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

ExtJS 4 ComboBox 下拉選單 change 事件失效:Store 重載導致監聽器丟失的解決

     編輯:程式設計綜合問答

問題現象

ComboBox 綁定 select 事件,切換選項時重新載入 TreeStore。第二次點擊同一選項或切回先前選項,事件不再觸發。

根本原因

  1. Store 重新賦值破壞綁定:menuTreeStore.proxy = new Ext.data.HttpProxy(...) 替換整個 Proxy,導致 Store 內部事件監聽器 (含 ComboBox 的選中狀態同步) 失效。
  2. ComboBox 的 queryMode: 'remote' 與手動 load() 衝突:遠端模式下 ComboBox 會自動管理載入,手動干預易亂。
  3. 缺乏快取破壞參數:瀏覽器/代理快取相同 URL 導致伺服器不回應,ComboBox 以為資料未變而不觸發 select。

修正方案

方案一:使用 setProxy + load() 並加時間戳 (快速修復)

listeners: {
    select: function(combo, record, index) {
        var projectName = combo.getRawValue();
        // 1. 更新 proxy url (不新建 proxy 實例)
        menuTreeStore.getProxy().setUrl(
            appBaseUri + '/sys/authority/getAuthority?globalRoleId=' + globalRoleId +
            '&projectName=' + encodeURIComponent(projectName) +
            '&_dc=' + Date.now()  // 關鍵:防快取
        );
        // 2. 重新載入
        menuTreeStore.load({
            callback: function(records, operation, success) {
                if (!success) Ext.Msg.alert('錯誤', '權限樹載入失敗');
            }
        });
    }
}

方案二:正規 ExtJS 5/6+ 寫法 —— ExtraParams + load

// 定義 Store 時使用 extraParams
var menuTreeStore = Ext.create('Ext.data.TreeStore', {
    autoLoad: false,
    proxy: {
        type: 'ajax',
        url: appBaseUri + '/sys/authority/getAuthority',
        extraParams: {
            globalRoleId: globalRoleId,
            projectName: '' // 初始空
        },
        reader: { type: 'json', root: 'children' }
    }
});

// ComboBox 選中時只更新 extraParams 並 load
listeners: {
    select: function(combo, record) {
        menuTreeStore.getProxy().setExtraParam('projectName', combo.getRawValue());
        menuTreeStore.getProxy().setExtraParam('_dc', Date.now()); // 防快取
        menuTreeStore.load();
    }
}

方案三:若 ComboBox 需根據專案動態載入自身 Store

var projects = Ext.create('Ext.data.JsonStore', {
    proxy: { type: 'ajax', url: appBaseUri + '/sys/project/getAll', reader: { type: 'json', root: 'list' } },
    fields: ['projectName', 'ItemValue'],
    autoLoad: true
});

// ComboBox 綁定 projects,select 事件只負責觸發 TreeStore 重載
var combo = Ext.create('Ext.form.ComboBox', {
    store: projects,
    queryMode: 'local', // 本地資料,不發遠端查詢
    displayField: 'projectName',
    valueField: 'ItemValue',
    listeners: {
        select: function(cb, rec) {
            menuTreeStore.getProxy().setExtraParams({
                globalRoleId: globalRoleId,
                projectName: rec.get('projectName'),
                _dc: Date.now()
            });
            menuTreeStore.load();
        }
    }
});

關鍵最佳實踐

  1. 不要重新 new Proxy,用 getProxy().setUrl() 或 setExtraParam()。
  2. 永遠加防快取參數 (_dc=Date.now()) 於 GET/POST URL。
  3. ComboBox queryMode 設正確:本地資料用 local,遠端搜尋用 remote。
  4. 事件用 select 而非 change:select 只在用戶主動選擇觸發,change 含程式設值干擾。

調試技巧

// 在 select 事件首行加入
console.log('[%s] select fired, value=%s', new Date().toISOString(), combo.getRawValue());
// 觀察 Console 是否每次點擊都輸出,若無則事件確實未觸發
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved