Dynamics CRM 365:无保存刷新页面且不触发未保存更改弹窗
解决方案:针对Dynamics 365 1612 (8.2.5.4)版本
一、优先方案:先撤销所有未保存更改,再刷新页面
你的需求核心是清除页面的脏状态——弹窗触发的根本原因就是存在未保存的字段修改。直接撤销所有未保存更改完全匹配你“不需要保存修改值”的诉求,是最稳妥的解决方式,具体代码如下:
// 撤销所有未保存的实体字段更改,恢复到页面加载时的初始状态 Xrm.Page.data.entity.revertChanges(); // 刷新当前实体页面(此时无脏字段,不会弹出确认弹窗) Xrm.Page.data.refresh(false); // 也可以用页面重载,效果一致: // window.location.reload();
为什么这个方法有效?
Xrm.Page.data.entity.revertChanges()会将所有字段值重置为页面加载时的初始状态,同时清除实体的脏标记(dirty state)。此时页面处于“无未保存更改”状态,无论用哪种方式刷新,都不会触发确认弹窗。
二、备选方案:移除Dynamics绑定的beforeunload事件(不推荐,稳定性差)
如果你确实需要保留当前修改的字段值(你的场景不需要,但可以作为参考),可以尝试移除Dynamics自身绑定的beforeunload事件。你之前的方法无效,大概率是因为CRM的事件绑定优先级更高。
以下代码尝试移除所有beforeunload事件(注意:该方法依赖浏览器事件模型,存在兼容性问题,且CRM版本更新后可能失效):
// 获取window的beforeunload事件处理函数列表 const eventListeners = getEventListeners(window).beforeunload || []; // 移除所有beforeunload事件 eventListeners.forEach(listener => { window.removeEventListener('beforeunload', listener.listener); }); // 执行刷新 window.location.reload();
三、关于“劫持保存函数”的可行性
你提到的劫持保存函数使其仅撤销脏字段,在旧版本中是可行的,但对你的场景来说没必要——因为你是通过自定义按钮触发流程,而非点击系统的“保存”按钮。如果确实需要修改系统保存行为,可以参考以下代码:
// 替换系统保存函数 const originalSave = Xrm.Page.data.entity.save; Xrm.Page.data.entity.save = function() { // 撤销脏字段而非执行保存 Xrm.Page.data.entity.revertChanges(); // 可选:提示用户操作结果 Xrm.Utility.alertDialog("已撤销所有未保存更改"); };
再次强调:你的场景用第一种方案(先撤销再刷新)是最优解,简单且稳定。
内容的提问来源于stack exchange,提问作者Pushtik
相关产品推荐
相关产品推荐

