Kendo Grid点击Cancel后隐藏按钮被恢复问题解决方案
Kendo Grid取消编辑后权限控制按钮重置问题解决方案
问题场景
项目基于Kendo Grid实现表格交互,需根据用户权限控制行操作、工具栏按钮的显隐规则:
- 低权限用户:仅展示行内「Edit」按钮
- 全权限用户:展示「Delete」行按钮、工具栏「Add」按钮
初期通过DOM操作实现显隐控制,代码如下:
$("#grid").find(".k-grid-delete").hide(); $("#grid").find(".k-grid-edit").show(); $("#grid").find(".k-grid-add").hide();
上述逻辑初始加载时运行正常,但存在稳定复现的异常:低权限用户点击Edit进入行编辑状态,再点击Cancel取消编辑时,Grid会执行内部重绘重置按钮状态,原本被隐藏的Delete、Add按钮会重新显示。
此前尝试的两种修复思路均未生效:
- 绑定Cancel事件,在回调中执行上述按钮隐藏逻辑:但Grid内部重绘逻辑在Cancel事件回调执行完成后才同步触发,回调中的DOM操作会被后续重绘覆盖
- 绑定
dataBound事件写入控制逻辑:取消编辑的操作不会触发该事件,逻辑无法执行
核心需求:找到可靠的执行时机挂载权限控制逻辑,确保所有场景下按钮显隐符合权限规则。
可行实现方案
方案1:从渲染源头控制按钮生成(最优,无兼容问题)
不要等按钮渲染完成后再通过hide()/show()修改DOM状态,直接在Grid初始化阶段通过配置项定义按钮的渲染规则,从根源避免重绘后状态重置:
- 工具栏Add按钮:根据权限动态生成工具栏配置,低权限用户不注入Add命令
- 行内Edit/Delete按钮:利用Kendo Grid命令列自带的
visible回调,传入权限判断逻辑,控制按钮是否渲染
示例代码:
// 提前完成权限判断 const isLowPermissionUser = /* 替换为实际权限校验逻辑 */ false; $("#grid").kendoGrid({ // 其余Grid配置项(数据源、编辑规则等)保持原有逻辑 toolbar: isLowPermissionUser ? [] : ["add"], columns: [ // 其余业务列配置保持不变 { command: [ { name: "edit", visible: () => true }, { name: "destroy", visible: () => !isLowPermissionUser } ], title: "操作", width: 200 } ], editable: "inline" });
该方案不需要额外绑定任何事件监听,不管是初始加载、取消编辑、重新刷新数据,Grid渲染时都会自动执行权限判断生成对应按钮,完全不会出现隐藏后被重绘覆盖的问题,也没有DOM操作带来的按钮闪烁问题。
方案2:调整Cancel事件内逻辑的执行时机(快速修复,改动最小)
不需要找重绘前触发的事件,利用JS事件循环机制,在cancel回调中用setTimeout将权限控制逻辑推入宏任务队列,等待Grid内部同步重绘逻辑执行完成后再运行DOM操作,就不会被重绘覆盖:
// 抽离统一的按钮权限控制函数,多处复用 function updateGridButtonAuth() { if (isLowPermissionUser) { $("#grid").find(".k-grid-delete").hide(); $("#grid").find(".k-grid-add").hide(); $("#grid").find(".k-grid-edit").show(); } } $("#grid").kendoGrid({ // 其余配置保持不变 cancel: function(e) { // 延迟0ms即可保证执行时机在Grid内部重绘完成后 setTimeout(updateGridButtonAuth, 0); } }); // 初始加载时执行一次 updateGridButtonAuth();
方案3:DOM变化监听(兜底兼容方案)
如果使用的Kendo版本存在事件兼容问题,可以通过MutationObserver监听Grid容器的DOM变化,只要检测到编辑态退出(编辑行class移除),就自动触发权限控制逻辑,不需要依赖Kendo官方事件:
const gridDom = document.querySelector("#grid"); const observer = new MutationObserver(() => { // 检测到当前不存在编辑行时,更新按钮状态 if (!gridDom.querySelector(".k-grid-edit-row")) { updateGridButtonAuth(); } }); // 监听Grid内部DOM、class变化 observer.observe(gridDom, { childList: true, subtree: true, attributes: true, attributeFilter: ["class"] });
内容的提问来源于stack exchange,提问作者CMPerez
相关产品推荐
相关产品推荐

