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

ExtJs技术求助:为表格元素添加Tooltip及动态循环渲染列

ExtJS表格开发问题解决方案

1. 表格单元格添加Tooltip(解决作用域问题)

方案1:利用data-qtip属性(最简实现)

ExtJS原生支持识别单元格的data-qtip属性自动生成Tooltip,无需额外处理作用域,直接在renderer中设置即可:

// 修改sell列renderer
renderer: function (value, gridcell, record) {
  value = record.get('sell')[4 - index];
  if (value) {
    gridcell.tdCls = 'sell';
    // 自定义Tooltip内容,替换为你需要的字段
    gridcell.set({
      'data-qtip': `数量:${value.quantity}\n备注:${value.remark || '无'}`
    });
    return ('Example' || '') + '<br />' + value.quantity;
  } else {
    gridcell.tdCls = '';
    gridcell.set({'data-qtip': ''}); // 清空无值单元格的Tooltip
    return '';
  }
}

// buy列和price列同理,在renderer中添加对应data-qtip设置

方案2:全局绑定Tooltip(复杂场景适用)

如果需要自定义Tooltip样式或逻辑,可在Grid初始化时创建全局Tooltip,通过scope绑定Grid实例解决作用域问题:

initComponent: function() {
  this.callParent(arguments);
  
  Ext.create('Ext.tip.ToolTip', {
    target: this.getView().el,
    delegate: '.x-grid-cell',
    trackMouse: true,
    renderTo: Ext.getBody(),
    listeners: {
      beforeshow: function(tip) {
        var cell = tip.triggerElement;
        var record = this.getView().getRecord(cell);
        var colIndex = this.getView().getCellIndex(cell);
        let tipText = '';
        
        // 根据列位置判断是sell/price/buy列,生成对应Tooltip内容
        const sellLen = record.get('sell').length;
        if (colIndex < sellLen) {
          const sellItem = record.get('sell')[sellLen - 1 - colIndex];
          tipText = sellItem ? `数量:${sellItem.quantity}` : '';
        } else if (colIndex === sellLen) {
          const totalQty = record.get('sell').reduce((sum, item) => sum + Number(item.quantity), 0) + 
                           record.get('buy').reduce((sum, item) => sum + Number(item.quantity), 0);
          tipText = `总价:${Common.Formatter.to4PrecisionPrice(record.get('price'))}\n总数量:${totalQty}`;
        } else {
          const buyIndex = colIndex - sellLen - 1;
          const buyItem = record.get('buy')[buyIndex];
          tipText = buyItem ? `数量:${buyItem.quantity}` : '';
        }
        
        tip.update(tipText);
        return !!tipText; // 无内容时不显示Tooltip
      },
      scope: this // 绑定Grid实例,确保能正确获取record和视图信息
    }
  });
}

2. 动态适配sell/buy数组长度生成列

实现思路

不再固定length:5,而是根据Store中第一条记录的sell、buy数组长度动态生成列,同时监听Store加载事件确保数据更新后列同步调整:

initComponent: function() {
  this.callParent(arguments);
  
  // 监听Store加载事件,动态生成列
  this.getStore().on('load', function(store) {
    if (store.isEmpty()) return;
    
    const firstRecord = store.first();
    const sellLen = firstRecord.get('sell').length;
    const buyLen = firstRecord.get('buy').length;
    
    // 生成sell列
    const sellColumns = Array.from({ length: sellLen }, (_, index) => ({
      renderer: function (value, gridcell, record) {
        value = record.get('sell')[sellLen - 1 - index];
        if (value) {
          gridcell.tdCls = 'sell';
          gridcell.set({'data-qtip': `数量:${value.quantity}`});
          return ('Example' || '') + '<br />' + value.quantity;
        } else {
          gridcell.tdCls = '';
          gridcell.set({'data-qtip': ''});
          return '';
        }
      },
      width: 100 // 自定义列宽
    }));
    
    // 中间的price列
    const priceColumn = {
      dataIndex: 'price',
      renderer: function (value, gridcell, record) {
        let quantity = 0;
        record.get('sell').forEach(num => quantity += Number(num.quantity));
        record.get('buy').forEach(num => quantity += Number(num.quantity));
        gridcell.tdCls = 'amount';
        gridcell.set({'data-qtip': `总价:${Common.Formatter.to4PrecisionPrice(value)}\n总数量:${quantity}`});
        return `${Common.Formatter.to4PrecisionPrice(value)}<br />${quantity}`;
      },
      width: 120
    };
    
    // 生成buy列
    const buyColumns = Array.from({ length: buyLen }, (_, index) => ({
      renderer: function (value, gridcell, record) {
        value = record.get('buy')[index];
        if (value) {
          gridcell.tdCls = 'buy';
          gridcell.set({'data-qtip': `数量:${value.quantity}`});
          return ('Example' || '') + '<br />' + value.quantity;
        } else {
          gridcell.tdCls = '';
          gridcell.set({'data-qtip': ''});
          return '';
        }
      },
      width: 100
    }));
    
    // 重新配置表格列
    this.reconfigure(store, [...sellColumns, priceColumn, ...buyColumns]);
  }, this);
  
  // 可选:监听Store数据变更事件,适配动态更新的数据
  this.getStore().on('datachanged', function(store) {
    // 重复上述列生成逻辑,或直接触发load事件处理函数
    this.getStore().fireEvent('load', store);
  }, this);
}

注意事项

  • 如果Store是预加载数据,可直接在initComponent中获取第一条记录生成列,无需监听load事件;
  • 若sell/buy数组长度在不同记录中不一致,需额外处理(比如取最大长度统一生成列)。

内容的提问来源于stack exchange,提问作者Michael

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 06:55:08