CRM365表格提供了;OnSave";事件,以便能够执行业务验证。如果其中一个验证失败,我们可以使用";executionContext.getEventArgs((.prventDefault(("以停止记录创建。验证当前表单的字段是很好的,但是,在某些情况下,验证还必须要求对实体记录执行查询。例如,创建房间预订必须检查是否有任何其他预先存在的预订,并在它们重叠时停止。问题是REST API调用是异步的,需要时间来执行和返回结果。当信息在响应中变为可用时;OnSave";函数被终止,记录基本上在没有验证的情况下被保存。
我的问题如下:
-
是";executionContext.getEventArgs((.prventDefault(("?我们可以停止保存操作;允许保存";有点说话吗?我尝试过;formContext.data.entity.save(("但由于我在";OnSave";事件,它创建了一个无限循环。我几乎无法想象这个标志可以设置但不能重置。
-
是否有任何有效的方法来停止Javascript或使其";睡眠;直到REST API数据可用?一切都围绕着SetTimeout函数,但这是一个非阻塞函数,当然,我的javascript只是运行它。
我确信我不是唯一遇到这种情况的人,解决这些基于REST API的验证必须是模式。
我可能应该补充一点,我正在寻找一个基于客户端的解决方案;所有这些都可以相对容易地在插件或自定义工作流中实现。
感谢您的时间和帮助。
我发现了这个链接,并在新的Dynamics试用版(2020年第2版(中进行了验证,XRM组件似乎在那里:
参考链接:https://community.dynamics.com/crm/b/dynamicscrmdevdownunder/posts/cancelling-save-event-based-on-the-result-of-async-operation
MSDN参考:https://learn.microsoft.com/en-us/powerapps/developer/model-driven-apps/clientapi/reference/formcontext-data-entity/addonsave
Save and Close
的其他注释:https://dreamingincrm.com/2017/10/12/cancelling-save-event-based-on-the-result-of-async-operation/
编辑以使其不是";仅链接";答案
- 使用
Clone
创建Xrm.Page.ui
和Xrm.Page.data.entity
的副本,这样,如果用户按下Save and Close
,这些对象仍然可用 - 创建使用
RetrieveMultiple
模拟异步验证过程的saveHandler
方法
代码:
Xrm.Page.data.entity.addOnSave((()=>{
let isSave = false;
var uiClone = parent.jQuery.extend(true, {}, Xrm.Page.ui);
var entityClone = parent.jQuery.extend(true, {}, Xrm.Page.data.entity);
var closeHandler = ()=>{
console.log('local. close blocked.');
};
var saveHandler = (ev)=>{
console.log('local. save blocked.');
Xrm.WebApi.retrieveMultipleRecords('systemuser','$select=fullname,jobtitle,homephone').then(x=>{
isSave = !x.entities.some(x=>x.homephone == '12345');
if(isSave){
Xrm.Page.data.entity.save = entityClone.save;
Xrm.Page.ui.close = uiClone.close;
if((typeof ev === 'string' && ev === 'saveandclose') ||
(ev.getEventArgs && ev.getEventArgs() && ev.getEventArgs().getSaveMode() === 2)){
console.log('saveandclose');
entityClone.save('saveandclose');
}
else{
console.log('save');
entityClone.save();
}
}
else{
console.log('User with homephone 12345 exists. Save blocked.');
}
});
};
return (e)=>{
var eventArgs = e.getEventArgs();
console.log(`DataXml OnSave: ${Xrm.Page.data.entity.getDataXml()}`);
console.log(`Save Mode: ${eventArgs.getSaveMode()}`);
if(isSave) {
console.log('proceed to save');
Xrm.Page.data.entity.save = entityClone.save;
Xrm.Page.ui.close = uiClone.close;
return;
}
else{
Xrm.Page.data.entity.save = saveHandler;
Xrm.Page.ui.close = closeHandler;
if(eventArgs.getSaveMode() !== 2){
eventArgs.preventDefault();
}
saveHandler(e);
}
}
})());
这个代码示例的所有功劳都归于原作者。