笔记

表单清空后,旧数据为什么又回来了?

编辑已有资料时,删掉最后一行电话号码,保存成功,再打开,号码却又回来了。输入框看着是空的,服务端收到的请求和页面保存后的状态,未必也空了。

这个问题出现在一套配置式表单中。界面字段需要转换成接口数据,详情返回后再反向转换。一个表格控件对应请求里的一个数组,删除行的意图可能在任意一段转换中丢失。

为什么跳过空值,会把旧值留下?

更新逻辑先复制原详情,再用表单值覆盖。这个办法能保留用户没有编辑的字段,但如果转换时遇到空字符串就跳过,旧值也会被保留。

例如原详情是 displayName: '旧名称',用户清空以后,表单值变成 ''。转换器不覆盖这个字段,请求就仍带着“旧名称”。对 false、0 使用同样的真假判断,还会误删正常值。

可选的处理方式有逐字段生成更新请求,或在旧详情上覆盖明确提交的字段。无论选哪种,都要先定义值的含义:

输入应当区分的意图
没有这个 key没编辑,或控件没有挂载
''清空文本
null明确置空可空字段
[]删除所有表格行
false、0正常值
undefined结合字段是否隐藏、是否挂载判断;JSON 不保留它
非法日期或错误类型校验失败,不能当作清空

项目保留了更新时合并原详情的方式,但先检查 key 是否存在,再按字段规则处理值。可见字段的空字符串可以覆盖旧值,允许置空的情况转换成 JSON 能提交的 null;隐藏控件未挂载产生的 undefined,则不能顺手清掉服务端数据。创建没有旧详情,部分空值仍可以省略。

用户删光了行,为什么提交值里没有空数组?

表单库的变更事件能报告 { phonesField: [] },完整表单快照却可能过滤空数组,连 key 都不留下。提交转换器只看快照,就会把“全部删除”理解成“没有修改”。

一种办法是调整表单库的取值规则;另一种是单独保留明确的删除意图。项目采用后者,记录当前可见、可编辑、允许整体清空的表格字段,生成提交快照时补回 []。

这个记录属于本次编辑。重新加入行后要撤销,切换记录、重置详情或换表单时也要清掉。测试时,变更事件应带 [],完整快照应故意缺 key,才能复现两份值不一致的情况。

请求已经清空,页面为什么还显示旧行?

还要看反向回填。服务端返回 phones: [],详情转换器却只处理非空数组,最后得到 {}。表单的赋值方法如果采用合并更新,缺少这个字段就会继续保留旧行。

项目因此在详情转换和通用行映射中都保留空数组:响应明确为空,就产生对应的空表格值,覆盖旧行;响应没有这个字段,则不由它修改当前值。只有非法脏行的响应也要单独处理,不能伪装成用户清空。

这样,同样的空数组在提交和回填两侧都有明确含义。

删除中间行时,未展示的属性怎么保留?

表格通常只展示原始记录的一部分。合并更新时若按行下标找旧数据,删除中间一行后,后面的隐藏属性就会配错行。

项目为加载进来的每行附带来源标识,优先使用原记录 ID,没有 ID 时使用本次加载的位置。编辑后凭这个标识找回原始行,再按写请求白名单保留允许提交的属性,最后去掉内部标识和只读字段。

位置标识只适用于本次加载基线,跨刷新或服务端重排需要稳定的行 ID 或版本信息。

返回上一页