Power Apps Web资源onChange事件JS未返回预期值问题求助
背景
现有一段实现Lookup字段联动的代码,在选择客户联系人时能自动填充所属客户公司,运行正常。但复用相同逻辑编写的、通过客户公司自动填充客户经理(CAM)Lookup字段的代码,触发onChange事件后报错。
正常运行的联系人联动公司代码
function setCompany(executionContext) { // 获取表单上下文 var formContext = executionContext.getFormContext(); // 获取客户公司字段 var targetCompany = formContext.getAttribute("w3g_clientcompany"); // 初始化Lookup字段值数组 var companyName = [{}]; // 检查客户联系人字段是否有值 if (formContext.getAttribute("w3g_clientcontact").getValue() !== null) { // 获取选中的联系人ID var selectedContactId = formContext.getAttribute("w3g_clientcontact").getValue()[0].id; // 查询选中的联系人记录 Xrm.WebApi.retrieveMultipleRecords("contact", "?$filter=contactid eq " + selectedContactId).then( function success(result) { for (var i = 0; i < result.entities.length; i++) { var thisContact = result.entities[i]; // 填充客户公司Lookup字段的属性 companyName[0].id = thisContact["_parentcustomerid_value"]; companyName[0].name = thisContact["_parentcustomerid_value@OData.Community.Display.V1.FormattedValue"]; companyName[0].entityType = thisContact["_parentcustomerid_value@Microsoft.Dynamics.CRM.lookuplogicalname"]; // 设置字段值并触发变更事件 targetCompany.setValue(companyName); targetCompany.fireOnChange(); } }, function (error) { console.log(error.message); } ); } }
该代码绑定在客户联系人Lookup字段的onChange事件上。
报错的公司联动CAM代码
function setCAM(executionContext) { // 获取表单上下文 var formContext = executionContext.getFormContext(); // 获取CAM字段 var targetCAM = formContext.getAttribute("w3g_cam"); // 初始化Lookup字段值数组 var CAMName = [{}]; // 检查客户公司字段是否有值 if (formContext.getAttribute("w3g_clientcompany").getValue() !== null) { // 获取选中的公司ID var selectedCompanyId = formContext.getAttribute("w3g_clientcompany").getValue()[0].id; // 查询选中的公司记录 Xrm.WebApi.retrieveMultipleRecords("account", "?$filter=accountid eq " + selectedCompanyId).then( function success(result) { for (var i = 0; i < result.entities.length; i++) { var thisCompany = result.entities[i]; // 填充CAM Lookup字段的属性 CAMName[0].id = thisCompany["_ownerid_value"]; CAMName[0].name = thisCompany["_ownerid_value@OData.Community.Display.V1.FormattedValue"]; CAMName[0].entityType = thisCompany["_ownerid_value@Microsoft.Dynamics.CRM.lookuplogicalname"]; // 设置字段值并触发变更事件 targetCAM.setValue(CAMName); targetCAM.fireOnChange(); } }, function (error) { console.log(error.message); } ); } }
该代码绑定在客户公司Lookup字段的onChange事件上。
控制台错误信息
Uncaught (in promise) UciError: Value should be of type: entityType: Parameter Name: value[0].entityType
at s (app.6ec6a5a348450479ff453caf37aa7414.js:33:899993)
at p (app.6ec6a5a348450479ff453caf37aa7414.js:4:160320)
at m (app.6ec6a5a348450479ff453caf37aa7414.js:4:160878)
at H.setValue (10.83a0bb90e152561aa38578b389b8f645.js:4:229830)
at success (cr214_AFCam:22:21)
at app.6ec6a5a348450479ff453caf37aa7414.js:14:465799
at i (app.6ec6a5a348450479ff453caf37aa7414.js:14:91380)
at a (app.6ec6a5a348450479ff453caf37aa7414.js:14:465792)
问题原因
- ownerid字段特性:系统字段
ownerid是多实体Lookup,可关联systemuser(用户)或team(团队),但你的w3g_cam字段应该只允许关联systemuser类型。如果公司的所有者是团队,返回的entityType会是team,与CAM字段的预期类型不匹配,导致报错。 - WebApi属性返回问题:默认情况下,
retrieveMultipleRecords不会自动返回@OData.Community.Display.V1.FormattedValue和@Microsoft.Dynamics.CRM.lookuplogicalname这类扩展属性,需要在查询中显式指定。
解决方案
修正后的代码
function setCAM(executionContext) { var formContext = executionContext.getFormContext(); var targetCAM = formContext.getAttribute("w3g_cam"); var companyAttr = formContext.getAttribute("w3g_clientcompany"); // 清空CAM字段(如果公司被清空) if (!companyAttr.getValue()) { targetCAM.setValue(null); targetCAM.fireOnChange(); return; } var selectedCompanyId = companyAttr.getValue()[0].id; // 显式请求需要的属性,包括扩展属性 var query = "?$filter=accountid eq " + selectedCompanyId + "&$select=_ownerid_value,_ownerid_value@OData.Community.Display.V1.FormattedValue,_ownerid_value@Microsoft.Dynamics.CRM.lookuplogicalname"; Xrm.WebApi.retrieveMultipleRecords("account", query).then( function success(result) { if (result.entities.length === 0) return; var thisCompany = result.entities[0]; var ownerId = thisCompany["_ownerid_value"]; var ownerName = thisCompany["_ownerid_value@OData.Community.Display.V1.FormattedValue"]; var ownerType = thisCompany["_ownerid_value@Microsoft.Dynamics.CRM.lookuplogicalname"]; // 仅当所有者是用户(systemuser)时,才填充CAM字段 if (ownerId && ownerType === "systemuser") { var CAMValue = [{ id: ownerId, name: ownerName, entityType: "systemuser" // 强制指定为systemuser,匹配CAM字段的预期类型 }]; targetCAM.setValue(CAMValue); targetCAM.fireOnChange(); } else { // 如果所有者是团队或为空,清空CAM字段 targetCAM.setValue(null); console.log("公司所有者不是用户,无法填充CAM字段"); } }, function (error) { console.log("查询公司记录失败: " + error.message); targetCAM.setValue(null); } ); }
关键修改点
- 显式请求扩展属性:在WebApi查询中添加
$select,确保获取到ownerid的格式化名称和实体类型。 - 过滤实体类型:仅当公司所有者是
systemuser时才填充CAM字段,避免团队类型导致的不匹配。 - 空值处理:添加公司字段为空时的清空逻辑,以及查询失败时的异常处理。
- 简化代码:去掉不必要的循环(查询单个记录时只会返回一条),优化逻辑结构。
内容的提问来源于stack exchange,提问作者dannydog

