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

动态修改列配置时Ag-Grid无法显示数据的问题排查

问题:Ag-Grid动态列配置后数据无法显示,重复新增columnDefs

我在组件中使用Ag-Grid展示数据,通过API调用获取响应后动态提取数据列名,传递给子组件展示,但数据无法显示。使用静态列配置(直接从变量获取)时功能正常。

静态列配置

export let DETIALCONFIG= {
    columnDefs: [
        {
            headerName: 'VT Name',
            field: 'vtName',
            hide: false,
            minWidth: 235,
            serverFlag: true,
            tooltipFields: 'veName'
        },
        {
            headerName: 'Key',
            field: 'KEY',
            hide: false,
            serverFlag: true,
        },
        {
            headerName: 'ID',
            field: 'ID',
            hide: true,
            serverFlag: true,
        },
        {
            headerName: 'APP Name',
            field: 'APP_NAME',
            hide: true,
            minWidth: 140,
            serverFlag: true,
        },
        {
            headerName: 'Status ',
            field: 'Status',
            hide: true,
            minWidth: 200,
            serverFlag: true,
        },
        {
            headerName: 'Version',
            field: 'VERSION',
            hide: true,
            minWidth: 235,
            serverFlag: true,
        },
        {
            headerName: 'Details',
            field: 'DETAILS',
            hide: true,
            minWidth: 235,
            serverFlag: true,
        },
        {
            headerName: 'Json',
            field: 'JSON',
            hide: true,
            minWidth: 235,
            serverFlag: true,
        },
    ],
    gridOptions: {
        domLayout: 'autoHeight',
        pagination: false,
        paginationPageSize: 6,
        rowSelection: 'multiple',
        enableColResize: true,
        enableSorting: true,
        enableFilter: true,
        suppressPropertyNamesCheck: true,
        enableBrowserTooltips: true,
        suppressAutoSize: true
    }
}

动态逻辑代码

private run = async (veName: string) => {
    let response: any
    try {
      response = await apiCall(veName, [], true)
      this.veTableData = [...response.data]
      const keys = Object.keys(this.veTableData[0])
      this.columnConfig = this.veDetailsGridConfig
      this.columnConfig.columnDefs.map((item: any) => {
        if(keys.includes(item.field)) {
          item.hide = false
          return item
        }
      })
      console.log(this.columnConfig)
      this.tableHeader = veName.toUpperCase()
    } catch (err) {
      this.veTableData = []
      this.columnConfig = this.veDetailsGridConfig
    }
}

使用动态逻辑时,模板中gridOptions绑定columnConfig后,每次都会新增一组columnDefs,静态配置无此问题,推测这是数据无法显示的原因,需要排查问题。


解决方案

问题根源

  1. 原始配置对象被污染:this.columnConfig = this.veDetailsGridConfig是直接赋值引用,而非创建新对象。每次修改columnDefs时都会直接修改原始的veDetailsGridConfig,导致后续调用时原始配置已经被修改,出现重复列的情况。
  2. map方法使用错误:map不会修改原数组,你的代码仅在回调中修改item,但未将返回的新数组赋值回去;同时未对不匹配数据字段的列重置hide状态,导致之前的修改状态残留。

修复步骤

1. 深拷贝原始配置,避免污染

每次使用配置时,都要创建原始配置的深拷贝,确保每次操作的都是独立对象:

// 用JSON方法深拷贝(注意:如果配置中有函数,此方法不适用,需用递归深拷贝)
this.columnConfig = JSON.parse(JSON.stringify(this.veDetailsGridConfig));

// 或者用扩展运算符手动拷贝(适合无函数的配置)
this.columnConfig = {
  ...this.veDetailsGridConfig,
  columnDefs: this.veDetailsGridConfig.columnDefs.map(item => ({...item}))
};

2. 正确设置列的显示/隐藏状态

使用forEach直接修改拷贝后的列配置,或用map返回新数组,确保所有列的hide状态都被正确重置:

// 方案1:forEach直接修改
this.columnConfig.columnDefs.forEach((item: any) => {
  // 匹配数据字段的列显示,不匹配的隐藏
  item.hide = !keys.includes(item.field);
});

// 方案2:map返回新数组(更符合不可变原则)
this.columnConfig.columnDefs = this.columnConfig.columnDefs.map((item: any) => ({
  ...item,
  hide: !keys.includes(item.field)
}));

3. 处理空数据场景

如果API返回空数据,要避免调用Object.keys(this.veTableData[0])导致报错,提前做判断:

修复后的完整代码

private run = async (veName: string) => {
  let response: any
  try {
    response = await apiCall(veName, [], true)
    this.veTableData = [...response.data]
    
    // 处理空数据
    if (this.veTableData.length === 0) {
      this.columnConfig = JSON.parse(JSON.stringify(this.veDetailsGridConfig));
      this.tableHeader = veName.toUpperCase()
      return;
    }

    const keys = Object.keys(this.veTableData[0])
    // 深拷贝原始配置
    this.columnConfig = JSON.parse(JSON.stringify(this.veDetailsGridConfig));
    // 统一设置列的显示隐藏
    this.columnConfig.columnDefs.forEach((item: any) => {
      item.hide = !keys.includes(item.field);
    })
    
    this.tableHeader = veName.toUpperCase()
  } catch (err) {
    this.veTableData = []
    // 出错时也使用干净的拷贝配置
    this.columnConfig = JSON.parse(JSON.stringify(this.veDetailsGridConfig))
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.01 19:43:22