切换日光/暗黑模式
091. 新建、取消、删除、统一保存与复制行
学习目标
这一节把行内编辑的基础闭环补齐。
学完后,你应该能理解:
- 前端临时 ID 保存时为什么要清理;
- 取消新建行和取消编辑行有什么区别;
- 删除接口如何接入通用表格;
- 为什么编辑状态下分页大小要临时变大;
- 如何统一保存多行数据;
- 为什么重复消息需要合并;
- 复制行时哪些字段不能复制。
临时 ID 的保存处理
新建行可能使用前端临时 ID。
例如以 new_ 开头。
这个 ID 只是为了让前端表格能稳定渲染。
保存到后端时,不能把它当成真实主键。
所以保存请求前要判断:
如果 ID 是前端生成的,就把它清理掉。
如果 ID 不是临时 ID,就保留。
这样后端可以为新增数据生成真正 ID。
取消编辑的两种情况
取消编辑要分两种情况。
第一种是已有数据。
它已经存在后端。
取消时只需要退出编辑状态,并重置表单值。
第二种是新建数据。
它还没有保存到后端。
取消时要从表格数据源里删除这条临时数据。
所以取消逻辑不能只移除编辑标记。
还要判断这条数据是不是新建数据。
删除新建数据
取消新建行时,需要做几件事:
- 找到目标行 ID;
- 判断这些 ID 是否在新建映射里;
- 从数据源中过滤掉这些新建行;
- 从新建映射里移除对应 ID;
- 从编辑映射里移除对应 ID。
这样取消后,临时新行会从界面上消失。
已有数据则只退出编辑状态,不会从数据源删除。
取消全部
取消方法可以接收行数据。
如果传了行数据,就取消指定行。
如果没有传,就取消当前所有编辑中的数据。
这让按钮栏里的“取消”可以统一取消所有新建和编辑行。
操作列里的“取消”可以只取消当前行。
编辑状态下的分页大小
新建多行时,如果分页大小仍然保持原值,新增行可能看不见。
例如每页显示 5 条。
新增第 6 条时,它会被分页截掉。
所以编辑状态下,分页大小要取一个更大的值。
例如:
ts
Math.max(pageSize, data.length)这样新建行能显示在当前页面。
但这个逻辑不能无脑一直使用。
保存完成后,还要恢复正常分页行为。
删除接口
删除功能接入通用模块接口。
删除时需要:
- 读取当前模块配置;
- 组装删除请求;
- 传入当前行 ID;
- 打开 loading;
- 请求完成后关闭 loading;
- 成功后重新加载当前页数据。
删除成功后,不只是本地删掉。
更稳妥的做法是重新加载当前页。
因为后端数据总数、分页、排序都可能变化。
当前页加载
重新加载当前页时,要注意前后端页码差异。
前端 UI 通常显示第 1 页、第 2 页。
后端分页和数据库偏移常常从 0 开始。
例如:
sql
LIMIT 3 OFFSET 0
LIMIT 3 OFFSET 3所以前端第 1 页传给后端时,可能要变成 0。
这个转换要集中处理,避免到处写 page - 1。
统一保存
按钮栏里的保存要保存所有编辑中的行。
做法是:
- 遍历当前数据;
- 找出处于编辑状态的行;
- 逐条调用已有的单行保存方法;
- 保存成功后清理编辑状态;
- 必要时重新加载数据。
这样单行保存和统一保存可以复用同一个核心保存逻辑。
不用写两套请求代码。
保存新建行
保存新建行时,会走新增接口。
保存已有行时,会走更新接口。
判断依据还是新建映射或临时 ID。
保存成功后,要用接口返回的数据替换表格里的临时数据。
因为后端会返回真实 ID、时间字段、关联字段等最终结果。
删除数据后的总数
删除或新增后,分页总数要更新。
如果接口返回了总数,就要写回分页状态。
否则界面可能显示旧页数。
例如删除最后一页数据后,如果总数没更新,分页仍然可能停留在错误页。
重复消息合并
批量保存多行时,如果每一行都提示“保存成功”,界面会连续弹出多条相同消息。
体验不好。
所以课程里封装了一个消息方法。
如果短时间内重复显示相同文本,就合并成一条。
再次触发时,只重置关闭计时。
这样批量保存时,用户只会看到一条稳定提示。
复制行
复制行本质上是拿当前行数据作为新建行初始值。
但不能复制所有字段。
例如:
- ID;
- 创建时间;
- 更新时间;
- 版本字段;
- 其他后端维护字段。
这些字段如果复制过去,会造成主键冲突或数据语义错误。
所以复制时要先把这些字段排除,再调用新建逻辑。
复制后仍然是新建
复制出来的数据不是原数据。
它应该是一条新数据。
所以复制后要:
- 生成新 ID 或临时 ID;
- 标记为新建数据;
- 进入编辑状态;
- 保存时走新增接口。
用户可以在复制出的基础上改字段,再保存成新记录。
行内编辑能力闭环
到这一节,通用表格已经具备基础行内编辑闭环。
包括:
- 新建行;
- 取消新建;
- 取消编辑;
- 删除行;
- 单行保存;
- 多行统一保存;
- 复制行;
- 保存提示合并。
后面可以在这个基础上继续封装表单编辑服务。
React 和当前设计的差异
课程里还提到一个写法差异。
普通 React 代码里,常常会尽量解构变量,并把精确变量放进依赖数组。
但在这个表格对象设计里,有些运行配置对象可能会被复制或替换。
如果过早解构,拿到的可能是旧引用。
所以这里更倾向于在使用时从 autoTable 或 runningConfig 上读取。
这和普通组件里的 Hook 写法不完全一样。
理解这个差异,可以避免把熟悉的 React 习惯机械套到表格框架内部。
这一节的核心
行内编辑真正可用,需要处理很多边界。
这一节补齐了最关键的几块:
- 新建行取消时要删除临时数据;
- 删除后要重新加载当前页;
- 统一保存复用单行保存;
- 批量提示要合并;
- 复制行要过滤后端维护字段;
- 前端页码和后端分页偏移要做好转换。
这些细节处理好后,表格才从“能编辑”变成“能在业务里使用”。