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

如何在不修改原有数据结构的前提下适配Ag-Grid Tree Data格式

无需修改原数据实现Ag-Grid三级树形结构

核心思路

通过包装原数据生成适配Ag-Grid树形结构的行数据,全程不修改原有数据对象,同时配置getDataPath、getChildNodes等函数实现三级树形展示(根节点:singleParent/couple → 父节点 → 子节点)。


1. 构造适配行数据

创建新对象包裹原数据,为每个节点添加path字段用于层级标识,同时将原children字段映射为自定义__children字段(避免冲突):

const prepareRowData = (originalData) => {
  // 递归包装节点,添加path字段,不修改原数据
  const wrapNode = (node, parentPath) => {
    const wrapped = { ...node };
    // 生成当前节点的路径数组
    wrapped.path = parentPath.concat(wrapped.name);
    // 处理子节点,映射为__children
    if (wrapped.children) {
      wrapped.__children = wrapped.children.map(child => wrapNode(child, wrapped.path));
      delete wrapped.children;
    }
    return wrapped;
  };

  // 生成根节点(singleParent和couple)
  return [
    {
      name: "singleParent",
      gender: "",
      path: ["singleParent"],
      __children: originalData.singleParent.map(node => wrapNode(node, ["singleParent"]))
    },
    {
      name: "couple",
      gender: "",
      path: ["couple"],
      __children: originalData.couple.map(node => wrapNode(node, ["couple"]))
    }
  ];
};

2. 配置Ag-Grid关键函数

getDataPath

返回节点的路径数组,用于Ag-Grid识别树形层级:

const getDataPath = useMemo(() => {
  return (data) => data.path;
}, []);

getChildNodes

告诉Ag-Grid去哪里读取子节点:

const getChildNodes = useMemo(() => {
  return (data) => data.__children || [];
}, []);

getRowId

生成唯一行ID(用路径拼接,避免重复):

const getRowId = useMemo(() => {
  return (params) => params.data.path.join("-");
}, []);

完整组件代码

const GridExample = () => {
  const containerStyle = useMemo(() => ({ width: "100%", height: "100%" }), []);
  const gridStyle = useMemo(() => ({ height: "100%", width: "100%" }), []);
  
  // 原有数据(保持不变)
  const originalData = useMemo(() => ({
    singleParent: [
      { name: "Karie", gender: "f", children: [{ name: "Emily", gender: "f" }, { name: "John", gender: "m" }] },
      { name: "Kade", gender: "f", children: [{ name: "sam", gender: "f" }, { name: "rick", gender: "m" }] },
    ],
    couple: [
      { name: "Jack & Jade", gender: "f", children: [{ name: "mike", gender: "f" }, { name: "loyd", gender: "m" }] },
      { name: "Taylor & Taylor", gender: "f", children: [{ name: "sophie", gender: "f" }, { name: "adam", gender: "m" }] },
    ]
  }), []);

  // 生成适配Ag-Grid的行数据
  const rowData = useMemo(() => prepareRowData(originalData), [originalData]);

  const [columnDefs] = useState([
    { field: "name" },
    { field: "gender" }
  ]);

  const defaultColDef = useMemo(() => ({
    flex: 1,
    filter: true,
    floatingFilter: true,
    sortable: true,
    resizable: true
  }), []);

  const getDataPath = useMemo(() => (data) => data.path, []);
  const getRowId = useMemo(() => (params) => params.data.path.join("-"), []);
  const getChildNodes = useMemo(() => (data) => data.__children || [], []);

  return (
    <div style={containerStyle}>
      <div className="example-wrapper">
        <div style={gridStyle} className="ag-theme-alpine">
          <AgGridReact
            rowData={rowData}
            columnDefs={columnDefs}
            defaultColDef={defaultColDef}
            treeData={true}
            animateRows={true}
            getRowId={getRowId}
            getDataPath={getDataPath}
            getChildNodes={getChildNodes}
          />
        </div>
      </div>
    </div>
  );
};

const root = createRoot(document.getElementById("root"));
root.render(
  <StrictMode>
    <GridExample />
  </StrictMode>
);

关键说明

  • 所有操作均为创建新对象包裹原数据,完全保留原有数据结构和引用,无任何修改。
  • 通过path字段明确层级关系,满足Ag-GridtreeData模式的getDataPath要求。
  • 自定义__children字段存储子节点,避免与原数据的children字段冲突,同时通过getChildNodes指定读取位置。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 20:43:14