ExtJS 3.0中实现通用的面板加载遮罩函数
Great question! The key here is to abstract the loading mask logic so it can target any panel (instead of hardcoding to Ext.getBody()) while maintaining request count tracking to handle concurrent AJAX calls properly. Here's how to build a fully reusable solution:
Step 1: Create Reusable Show/Hide Mask Functions
Add these methods to your Util namespace. They’ll handle targeting a specific panel, tracking active requests, and managing the mask instance efficiently:
// Show loading mask for a specified panel Util.ShowPanelLoadingMask = function(panel, customMsg) { // Resolve panel from selector or use the instance directly const targetPanel = Ext.isString(panel) ? Ext.ComponentQuery.query(panel)[0] : panel; if (!targetPanel) { console.warn('Target panel not found - cannot apply loading mask'); return; } // Initialize request counter for the panel if it doesn't exist if (!targetPanel.ajaxRequestCount) { targetPanel.ajaxRequestCount = 0; } targetPanel.ajaxRequestCount++; // Only show the mask if this is the first active request for the panel if (targetPanel.ajaxRequestCount === 1) { // Reuse existing mask or create a new one if (!targetPanel.loadMask) { targetPanel.loadMask = new Ext.LoadMask(targetPanel.el, { msg: customMsg || 'Please wait...' }); } targetPanel.loadMask.show(); } }; // Hide loading mask for a specified panel Util.HidePanelLoadingMask = function(panel) { const targetPanel = Ext.isString(panel) ? Ext.ComponentQuery.query(panel)[0] : panel; if (!targetPanel || !targetPanel.ajaxRequestCount) { return; } targetPanel.ajaxRequestCount--; // Hide mask only when all requests for the panel are done if (targetPanel.ajaxRequestCount <= 0) { targetPanel.ajaxRequestCount = 0; // Reset to avoid negative values if (targetPanel.loadMask) { targetPanel.loadMask.hide(); } } };
Step 2: Update Your AJAX Function to Integrate the Mask
Modify your existing AJAX method (renamed to something more descriptive below) to accept a targetPanel parameter and use the new mask functions:
Util.makeAjaxRequest = function(url, postData, scope, successCallback, callerFunctionName, responseType, httpMethod, failureCallback, targetPanel) { // Show mask for the specified panel before starting the request Util.ShowPanelLoadingMask(targetPanel); // Check session first - hide mask if session is invalid if (!this.SessionExists()) { Util.HidePanelLoadingMask(targetPanel); return; } Ext.Ajax.request({ url: url, method: httpMethod || 'POST', params: postData, responseType: responseType, scope: scope || this, success: function(response) { successCallback?.call(this, response); // Hide mask after successful request Util.HidePanelLoadingMask(targetPanel); }, failure: function(response) { failureCallback?.call(this, response); // Hide mask even if request fails Util.HidePanelLoadingMask(targetPanel); } }); };
Step 3: Use the Function with Any Panel
Now you can reuse this across all your panels by just passing the target panel (either as an instance or a selector):
Example 1: Using a Panel Instance
// Get your panel instance (e.g., by ID) const userPanel = Ext.getCmp('user-management-panel'); // Call the AJAX function with the panel as the target Util.makeAjaxRequest( '/api/users', { role: 'admin' }, this, this.onUsersLoaded, 'loadAdminUsers', 'json', 'GET', this.onLoadFailed, userPanel );
Example 2: Using a Selector
If you don’t have the panel instance handy, use a ComponentQuery selector:
Util.makeAjaxRequest( '/api/products', {}, this, this.onProductsLoaded, 'loadProducts', 'json', 'GET', this.onLoadFailed, '#product-grid-panel' );
Example 3: Custom Mask Message
You can also pass a custom message when showing the mask directly:
Util.ShowPanelLoadingMask(userPanel, 'Loading admin users...'); // Later, when done: // Util.HidePanelLoadingMask(userPanel);
Key Benefits of This Approach
- Full Reusability: Works with any Ext JS panel or component that has an
elproperty. - Concurrent Request Handling: The
ajaxRequestCounton each panel ensures the mask stays visible until all pending requests for that panel are complete. - Efficient: Reuses the same mask instance for a panel instead of creating new ones every time.
- Robust: Handles cases where the target panel isn’t found gracefully.
内容的提问来源于stack exchange,提问作者rajib86

