如何用PrimeReact确定展开行按钮所属的父容器行?
解决PrimeReact DataTable展开行子项获取父容器行数据的问题
背景与场景
使用PrimeReact的DataTable组件实现层级结构:主表行代表容器,展开后显示容器内的子项列表,子项带有操作按钮(如删除)。操作子项时需要同时获取子项数据和所属父容器行的数据,用于构造API请求。
示例代码(原问题)
<DataTable value={rootList}> <Column body={buttonAction} /> </DataTable> const buttonAction = (data: any, props: any) => { return <Button type="button" onClick={(e) => { // props仅包含子行信息,无法获取父容器行数据 }} ></Button>; };
当前问题
子项操作按钮的回调中只能获取到子行自身的数据,无法直接关联到所属的父容器行。
曾尝试方案
尝试限制仅允许同时展开一行,直接使用当前展开的根行,但未找到最优实现方式。
正确实现方法
方法1:在展开行模板中传递父容器数据
利用DataTable的expandedRowTemplate属性,在渲染子项列表时直接将父容器行数据传递给子项的操作按钮回调,无需限制展开行数。
import { DataTable, Column, Button } from 'primereact'; // 主表组件 <DataTable value={rootList} expandedRowTemplate={(parentRowData) => { // parentRowData即为当前展开的父容器行数据 return ( <div className="p-p-3"> {/* 渲染子项列表,这里以DataTable为例 */} <DataTable value={parentRowData.children}> <Column field="itemName" header="子项名称" /> <Column body={(childRowData) => handleChildAction(childRowData, parentRowData)} header="操作" /> </DataTable> </div> ); }} > <Column field="containerName" header="容器名称" /> </DataTable> // 子项操作按钮回调 const handleChildAction = (childData, parentData) => { return ( <Button type="button" label="删除" onClick={() => { // 同时获取子项和父容器数据 console.log("父容器ID:", parentData.id); console.log("子项ID:", childData.id); // 构造API请求:例如 DELETE /containers/{parentId}/items/{childId} }} /> ); };
方法2:限制单一行展开(补充实现)
如果业务场景确实需要限制仅展开一行,可以通过rowExpansionMode="single"属性快速实现,同时结合状态获取当前展开的父行:
import { useState } from 'react'; import { DataTable, Column, Button } from 'primereact'; const [expandedRows, setExpandedRows] = useState({}); const [currentParentRow, setCurrentParentRow] = useState(null); const onRowExpand = (event) => { // 记录当前展开的父容器行 setCurrentParentRow(event.data); }; <DataTable value={rootList} expandedRows={expandedRows} onRowExpand={onRowExpand} rowExpansionMode="single" // 开启单行展开模式 onRowCollapse={() => setCurrentParentRow(null)} > <Column field="containerName" header="容器名称" /> <Column body={(childData, props) => { return ( <Button type="button" label="删除" onClick={() => { // 使用currentParentRow获取父容器数据 if (currentParentRow) { console.log("父容器数据:", currentParentRow); console.log("子项数据:", childData); } }} /> ); }} /> </DataTable>
说明:方法1更通用,无需限制用户操作;方法2适用于必须单一行展开的业务场景。
内容的提问来源于stack exchange,提问作者StevenPG
相关产品推荐
相关产品推荐

