ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

如何在 Refine Ant Design 中配合 useEditableTable 实现表格内行内编辑?

如何在 Refine Ant Design 中配合 useEditableTable 实现表格内行内编辑? 如何在 Refine Ant Design 中配合 useEditableTable 实现表格内行内编辑【免费下载链接】refineA React Framework for building internal tools, admin panels, dashboards B2B apps with unmatched flexibility.项目地址: https://gitcode.com/GitHub_Trending/re/refine如果你的 Ant Design 列表页目前只能整页跳转去编辑而希望用户直接在表格行内修改某个字段并保存Refine 的refinedev/antd包提供了useEditableTablehook 来完成这件事。它由useTable扩展而来返回可以直接铺到 Ant DesignTable和Form上的属性以及控制“哪一行正在编辑”的一组按钮属性和方法。本文以官方示例工程table-antd-use-editable-table的帖子posts列表为例走通从项目创建、页面改造到保存验证的完整路径。准备条件获取示例工程仓库中的完整示例位于 examples/table-antd-use-editable-tableREADME 给出的本地获取命令是npm create refine-applatest -- --example table-antd-use-editable-table该示例的依赖版本以工程 package.json 为准refinedev/antd^6.0.3、antd^5.23.0、react^19.1.0且engines要求node 20。数据层使用refinedev/simple-rest接口地址在 App.tsx 中配置const API_URL https://api.fake-rest.refine.dev; Refine dataProvider{dataProvider(API_URL)} routerProvider{routerProvider} resources{[{ name: posts, list: /posts }]} notificationProvider{useNotificationProvider} options{{ syncWithLocation: true, warnWhenUnsavedChanges: true }} 其中notificationProvider{useNotificationProvider}来自refinedev/antd用于在请求后弹出成功/失败提示resources中的list: /posts决定了列表页路由路由部分由 App.tsx 中的Route path/posts element{PostList /} /挂载。如果你的项目已有 Refine 应用且数据来自其他接口保留自己现有的dataProvider即可本文后续的页面代码只依赖列表数据有唯一id字段。示例的数据结构定义在 interfaces/index.d.tsexport interface IPost { id: number; title: string; }第一步用 Form 包住 TableuseEditableTable的核心用法是调用 hook 拿到tableProps和formProps把Table用Form包住并给表格指定rowKeyid文档示例中rowKey固定为id对应数据记录的主键字段名你的字段名不同就改成实际主键字段import { List, useEditableTable } from refinedev/antd; import { Table, Form } from antd; export const PostList: React.FC () { const { tableProps, formProps } useEditableTableIPost(); return ( List Form {...formProps} Table {...tableProps} rowKeyid Table.Column dataIndexid titleID / Table.Column dataIndextitle titleTitle / /Table /Form /List ); }; interface IPost { id: number; title: string; }这一步只是把表格接上了行内编辑的表单基础设施此时任何单元格都还不可编辑。第二步给每行加“编辑 / 保存 / 取消”操作列从 hook 中再解构出isEditing、saveButtonProps、cancelButtonProps、editButtonProps然后新增一个 Actions 列。判断逻辑是isEditing(record.id)返回true时说明该行正处于编辑态展示 Save 和 Cancel 按钮否则展示 Edit 按钮const { tableProps, formProps, isEditing, saveButtonProps, cancelButtonProps, editButtonProps, } useEditableTableIPost();Table.ColumnIPost titleActions dataIndexactions keyactions render{(_text, record) { if (isEditing(record.id)) { return ( Space SaveButton {...saveButtonProps} sizesmall / Button {...cancelButtonProps} sizesmall Cancel /Button /Space ); } return ( Space EditButton {...editButtonProps(record.id)} sizesmall / /Space ); }} /三个按钮属性都来自 hook 返回editButtonProps接收行id作为参数点击时会让该行进入编辑态saveButtonProps是提交按钮的 propscancelButtonProps的onClick会被useEditableTable覆盖为把编辑 id 重置为undefined即退出编辑态。SaveButton、EditButton、List均从refinedev/antd导入Space、Button从antd导入。第三步让目标列在编辑态下显示输入框默认情况下即使进入了编辑态列里的值也只是普通文本。要让某列可编辑需要给Table.Column提供render当isEditing(record.id)为true时返回一个带name的Form.Item包裹antd的Input否则渲染只读值。这就是文档所说的“条件渲染”Form.Item的name要与可编辑字段一致Table.ColumnIPost keytitle dataIndextitle titleTitle render{(value, record) { if (isEditing(record.id)) { return ( Form.Item nametitle style{{ margin: 0 }} Input / /Form.Item ); } return TextField value{value} /; }} /按文档的说明用户点击编辑按钮后isEditing(lineId)对相关行变为true正在编辑的行上出现输入框编辑完成后点击 SaveButton 即可保存新值。TextField来自refinedev/antd非编辑态时用于展示原始值。可选分支点击行直接进入编辑态除了按钮触发文档给出了另一种方式利用Table的onRow属性在行被点击时调用useEditableTable返回的setId把该行置为编辑态const { tableProps, formProps, isEditing, setId } useEditableTableIPost(); Table {...tableProps} rowKeyid onRow{(record) ({ onClick: (event: any) { if (event.target.nodeName TD) { setId setId(record.id); } }, })} event.target.nodeName TD这个判断保留了文档原样只有点击落在单元格上才触发进入编辑点击行内的其他元素比如按钮不会触发。两种方式可以并存也可以只用其中一种。完整实现官方示例工程中的最终页面在 src/pages/posts/list.tsx把上述按钮、可编辑列和点行编辑组合在了一起import { List, SaveButton, EditButton, TextField, useEditableTable, } from refinedev/antd; import { Table, Form, Space, Button, Input } from antd; import type { IPost } from ../../interfaces; export const PostList () { const { tableProps, formProps, isEditing, setId: setEditId, saveButtonProps, cancelButtonProps, editButtonProps, } useEditableTableIPost(); return ( List Form {...formProps} Table {...tableProps} rowKeyid onRow{(record) ({ // eslint-disable-next-line onClick: (event: any) { if (event.target.nodeName TD) { setEditId?.(record.id); } }, })} Table.Column dataIndexid titleID / Table.ColumnIPost dataIndextitle titleTitle render{(value, record) { if (isEditing(record.id)) { return ( Form.Item nametitle style{{ margin: 0 }} Input / /Form.Item ); } return TextField value{value} /; }} / Table.ColumnIPost titleActions dataIndexactions render{(_, record) { if (isEditing(record.id)) { return ( Space SaveButton {...saveButtonProps} hideText sizesmall / Button {...cancelButtonProps} sizesmall Cancel /Button /Space ); } return ( EditButton {...editButtonProps(record.id)} hideText sizesmall / ); }} / /Table /Form /List ); };运行与结果验证在示例工程根目录执行npm run dev对应脚本为refine dev访问/posts路由打开帖子列表按文档描述的行为逐项核对点击某行的 Edit 按钮或直接点击该行任意单元格nodeName为TD时后该行的 Title 列从只读文本切换为输入框Actions 列切换为 Save 和 Cancel——这说明isEditing(record.id)已对该行返回true修改标题后点击 Save 按钮提交成功后行内编辑关闭、表格展示新值文档指出这由autoSubmitClose行为保证该选项默认为trueuseEditableTable会在提交成功后自动以undefined调用setId让该行退出编辑态。若希望保存后仍停留在编辑态可在 hook 中显式关闭const editableTable useEditableTable({ autoSubmitClose: false, });点击 Cancel 按钮该行退出编辑态且不提交改动cancelButtonProps的默认行为是把编辑 id 重置为undefined。提交状态本身也可以通过 hook 返回的mutation表单提交触发的 mutation 结果和formLoading表单请求加载态在自定义 UI 中消费示例工程则通过useNotificationProvider统一弹出请求结果提示。限制与可参考的文档useEditableTable继承useTable因此useForm与useTable的全部属性和返回值在useEditableTable中都可用如searchFormProps、tableQuery、sorter、filters、query等需要排序、筛选或搜索参数时可直接沿用无需换成useTable文档中autoSubmitClose的默认值是trueisEditing、setId、saveButtonProps、cancelButtonProps、editButtonProps的返回签名见 useEditableTable hook 文档 的 “Return values” 表格该示例的在线预览入口CodeSandboxExample工程路径table-antd-use-editable-table在 示例文档页 中可直接对照运行效果。【免费下载链接】refineA React Framework for building internal tools, admin panels, dashboards B2B apps with unmatched flexibility.项目地址: https://gitcode.com/GitHub_Trending/re/refine创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表