如何在不修改原有数据结构的前提下适配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
相关产品推荐
相关产品推荐

