You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ExtJS 3.0中实现通用的面板加载遮罩函数

Reusable Loading Mask Function for Specific Ext JS Panels

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 el property.
  • Concurrent Request Handling: The ajaxRequestCount on 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 04:06:55