D365 CRM中JS替换动态字段值异常问题求助
Dynamics 365 CRM 动态占位符替换问题修复
问题根源
你的代码存在三个核心问题,导致替换结果不符合预期:
占位符匹配错误
代码中使用fieldName作为正则匹配目标,但实际需要替换的是commandText中<User Name>、<User Age>这类被尖括号包裹的占位符。当前匹配逻辑完全偏离目标,无法正确定位要替换的动态字段标记。异步请求并发导致状态覆盖
forEach循环中并行发起多个Xrm.WebApi.retrieveRecord请求,每个请求的回调函数都基于原始的commandText进行替换(异步请求执行时,回调外的commandText还未被修改)。最终多个独立的替换结果相互干扰,出现重复文本的情况。提前执行updateBody
代码末尾直接调用updateBody,此时异步请求尚未完成,replacedValues还是初始空字符串,这会导致错误的提前赋值,甚至可能和后续异步完成后的赋值冲突。
修复方案
- 修正占位符匹配逻辑:根据
templatefield记录的name字段,构造对应的尖括号包裹的正则表达式(比如<User Name>),确保精准匹配目标占位符。 - 串行处理异步请求:使用
async/await将并行的异步请求改为串行执行,确保每次替换都基于上一次替换后的结果,避免状态覆盖。 - 移除提前的updateBody调用:仅在所有异步替换完成后,调用
updateBody设置最终结果。
修正后的代码
retrieveAndReplaceDynamicFieldValues: async function (formContext, fieldName, commandText, English, NonEnglish, Language) { try { // 1. 获取templatefield记录 const templatefields = await Xrm.WebApi.retrieveMultipleRecords( "templatefield", `?$select=entity,fieldschemaname,name&$filter=name eq '${fieldName}'` ); let updatedCommandText = commandText; // 2. 串行处理每个templatefield记录 for (const TemplateResult of templatefields.entities) { const entityName = TemplateResult["entity@OData.Community.Display.V1.FormattedValue"].toLowerCase(); const fieldSchemaName = TemplateResult.fieldschemaname; const placeholderName = TemplateResult.name; // 假设name字段是"User Name"这类占位符名称 // 获取记录GUID const RecordGUID = retrieveGuid(formContext, entityName); // 获取字段值 const result = await Xrm.WebApi.retrieveRecord( entityName, RecordGUID, `?$select=${fieldSchemaName}` ); const fieldValue = result[fieldSchemaName]; // 构造正则表达式,匹配<User Name>这类占位符 const placeholderRegex = new RegExp(`<${placeholderName}>`, 'gi'); // 替换占位符 updatedCommandText = updatedCommandText.replace(placeholderRegex, fieldValue); } // 3. 所有替换完成后更新内容 updateBody(English, NonEnglish, Language, updatedCommandText); } catch (error) { console.error("处理动态字段替换时出错:", error.message); } },
关键说明
- 假设
templatefield实体的name字段存储的是占位符的核心名称(比如"User Name"),如果实际存储的是带尖括号的完整占位符(比如""),则正则表达式改为 new RegExp(placeholderName, 'gi')即可。 - 使用
async/await需要确保当前运行环境支持ES2017及以上语法(Dynamics 365 Online环境已支持)。 - 移除了原代码中多余的
completedIterations计数器,通过for...of串行循环自然保证所有操作完成后再执行最终的updateBody。
内容的提问来源于stack exchange,提问作者Kavi
相关产品推荐
相关产品推荐

