必须在blur或keydown.enter时校验并首行e.preventdefault(),否则非法值已污染缓存;动态绑定事件、清理旧监听、禁用输入框防连点;校验失败需同步还原input、td文本和cache;成功后仅updatecell+手动改td,禁用reloaddata。
不能靠 table.on('edit') 里写校验逻辑就完事——这个事件触发时值已经写进缓存和 dom,再拦也晚了。必须在用户离开编辑框(blur 或 keydown.enter)时才校验,且第一件事是调用 e.preventdefault() 拦住默认落库行为。
edit 事件里为什么必须第一行写 e.preventDefault()
Layui 的单元格编辑默认是“改完即生效”:双击→弹 input→失焦/回车→立刻更新 table.cache 和对应 td 文本。不加 e.preventDefault(),校验还没跑完,非法值就已经污染了数据源。
-
e.value是用户刚输的字符串,e.oldValue是原始值(但部分版本可能为undefined,稳妥起见建议从 DOM 取:e.tr.find('td[data-field="' + e.field + '"]').text().trim()) - 拦截后,所有后续操作(恢复输入框、发请求、提示错误)才有意义;否则你清空 input,缓存里还是错的
- 别在回调末尾
return false——它不撤回修改,只终止后续监听器执行
怎么在失焦或回车时触发校验而不重复绑定
直接给 input 绑 blur 容易因表格重绘丢失事件;在 edit 回调里动态绑一次最稳。
- 用
layui.jquery.one('blur', e.elem, function() { ... }),确保只响应下一次失焦 - 或监听
keydown,判断e.keyCode === 13,然后e.preventDefault()阻止换行 - 绑定前先清理旧事件:
$(e.elem).off('blur keydown'),避免多次点击生成多个 pending 请求 - 请求发出前给
input加disabled或 classlay-editing,防止连点提交
校验失败后如何还原并准确定位提示
还原不只是改 input 值,还要同步 DOM 文本和缓存,否则表格显示和真实数据对不上。
- 恢复输入框:
e.tr.find('td[data-field="' + e.field + '"] input').val(oldValue) - 恢复 td 文本:
e.tr.find('td[data-field="' + e.field + '"]').text(oldValue) - 手动更新 cache:
table.cache['yourFilter'][e.trIndex][e.field] = oldValue(注意e.trIndex是渲染序号,不是数据索引) - 提示用
layer.tips(msg, e.tr.find('td[data-field="' + e.field + '"]'), {tips: [1, '#ff6a00']}),每次调用前先layer.close(tipsIndex)清旧提示
验证通过后为什么不能调 table.reloadData()
table.reloadData() 会销毁所有编辑态实例,正在 focus 的 input 直接消失,刚改的值也可能被接口返回的老数据覆盖。
- 成功后只做两件事:
table.updateCell({id: e.id, field: e.field, value: e.value.trim()})+ 手动改td文本 -
e.id必须匹配你 render 时配置的id: 'xxx'字段,否则updateCell找不到目标行 - 如果字段名含点(如
user.phone),访问 cache 时得写成cache[index]['user']['phone'],不能直接cache[index]['user.phone'] - 正则别图省事用
.*@.*\..*,邮箱至少用/^[^\s@]+@[^\s@]+\.[^\s@]+$/,数字校验前先.trim()再parseFloat+!isNaN
真正卡住人的从来不是正则怎么写,而是 e.id 对不上主键、data-field 属性漏写、或者 templet 列意外禁用了 edit ——这三个地方错一个,编辑就静默失效,控制台连报错都没有。











