在 ExtJS 專案開發中,常遇到這樣的場景:點擊按鈕彈出確認對話框,用戶點擊「是」後需執行回調函數,且該回調函數需要用到某個對象(例如 Ext.grid.GridEditor 實例)。初學者往往會直接在處理函數內部定義回調,導致作用域問題或函數未定義錯誤。
handler: function() {
Ext.MessageBox.confirm('提示', '確實要保存修改記錄?', DOSave);
}
這裡 DOSave 定義在外部,但無法訪問 handler 內部的 grid 變量。Firebug 調試提示找不到 DOSave 方法,原因可能是函數嵌套定義導致的作用域混亂。
handler: function() {
Ext.MessageBox.confirm('提示', '確實要保存修改記錄?', DOSave(grid));
}
這樣寫雖然解決了參數傳遞,但引發新問題:對話框尚未彈出,DOSave 已經執行了。這是因為 DOSave(grid) 是直接函數調用,而非回調函數引用。
借鑒社區經驗,使用匿名函數包裝回調,既能延遲執行,又能捕獲外部變量:
handler: function() {
Ext.MessageBox.confirm('提示', '確實要保存修改記錄?', function() {
DOSave(grid);
});
}
將 DOSave 定義在外部作用域,斷點調試確認 grid 對象完整保持為 Ext.grid.GridEditor 類型。這利用了 JavaScript 閉包特性,完美解決參數傳遞與執行時機問題。
DOSave)建議定義在外部,保持代碼結構清晰這個技巧不僅適用於 Ext.MessageBox,同樣適合 ExtJS 其他組件的回調場景,是掌握 ExtJS 事件處理的關鍵基礎。