You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

D365中JS动态生成的选项集无法选中选项问题求助

问题现象
  • 自定义选项集字段通过代码动态填充实体列表成功,但选中选项后字段无法赋值、选项不保持选中状态
  • 为该字段配置的OnChangeOfEntity事件从未触发
问题根源
  1. 选项值与后端定义不兼容
    动态添加选项时使用i+1作为value,但Dynamics 365要求前端选项值必须与该字段在Dataverse中预先定义的选项值匹配。如果后端没有对应值,系统无法识别选中操作,导致无法赋值和触发事件。

  2. OnChange事件注册逻辑冗余混乱
    OnChangeOfEntity本身是表单配置的字段OnChange事件处理程序,但内部又调用optionSetField.addOnChange()添加额外处理器,既冗余又会导致事件触发逻辑失效。

  3. 重复加载的潜在状态异常
    表单重复加载(如快速切换表单)时,重复清空添加选项可能导致控件状态异常。

修复方案

1. 修正选项值生成逻辑

使用实体的MetadataId作为选项值(唯一且稳定),确保前端选项与后端字段兼容:

// 表单加载事件处理函数
function OnLoad(executionContext) {
    var formContext = executionContext.getFormContext();
    var optionSetField = formContext.getAttribute("zzz_entity");

    GetEntityDefinitions().then(function(entities) {
        // 清空现有选项
        optionSetField.controls.forEach(function(control) {
            control.clearOptions();
        });

        // 添加空选项(可选,根据业务需求调整)
        optionSetField.controls.forEach(function(control) {
            control.addOption({ text: "", value: null });
        });

        // 用实体MetadataId作为选项值添加选项
        entities.forEach(function(entity) {
            var option = {
                text: entity.LogicalName,
                value: entity.MetadataId
            };
            optionSetField.controls.forEach(function(control) {
                control.addOption(option);
            });
        });
    }).catch(function(error) {
        console.error("加载实体列表失败:", error);
    });
}

// 获取包含MetadataId的实体定义
function GetEntityDefinitions() {
    return new Promise(function(resolve, reject) {
        var req = new XMLHttpRequest();
        req.open("GET", Xrm.Utility.getGlobalContext().getClientUrl() + "/api/data/v9.0/EntityDefinitions?$select=LogicalName,MetadataId", true);
        req.setRequestHeader("OData-MaxVersion", "4.0");
        req.setRequestHeader("OData-Version", "4.0");
        req.setRequestHeader("Accept", "application/json");
        req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
        req.onreadystatechange = function() {
            if (this.readyState === 4) {
                req.onreadystatechange = null;
                if (this.status === 200) {
                    var results = JSON.parse(this.response);
                    resolve(results.value);
                } else {
                    reject(new Error('请求失败,状态码: ' + this.status + ', 状态信息: ' + this.statusText));
                }
            }
        };
        req.send();
    });
}

2. 修正OnChange事件处理逻辑

直接在OnChangeOfEntity中编写业务逻辑,无需额外注册处理器,确保函数直接绑定到字段的OnChange事件:

function OnChangeOfEntity(executionContext) {
    var formContext = executionContext.getFormContext();
    var optionSetField = formContext.getAttribute("zzz_entity");

    var selectedValue = optionSetField.getValue();
    if (selectedValue != null) {
        var selectedText = optionSetField.getText();
        console.log("选中的实体值: " + selectedValue);
        console.log("选中的实体名称: " + selectedText);

        GetEntityCollectionName(selectedText)
            .then(function(entityCollectionName) {
                formContext.getAttribute("zzz_entityCollection").setValue(entityCollectionName);
            })
            .catch(function(error) {
                console.error(error);
            });
    } else {
        console.log("zzz_entity字段未选中任何选项");
        formContext.getAttribute("zzz_entityCollection").setValue(null);
    }
}

// 获取实体集合名称(移除冗余变量声明)
function GetEntityCollectionName(entityName) {
    return new Promise(function(resolve, reject) {
        var req = new XMLHttpRequest();
        req.open("GET", Xrm.Utility.getGlobalContext().getClientUrl() + "/api/data/v9.0/EntityDefinitions?$select=LogicalName,CollectionName&$filter=LogicalName eq '" + entityName + "'", true);
        req.setRequestHeader("OData-MaxVersion", "4.0");
        req.setRequestHeader("OData-Version", "4.0");
        req.setRequestHeader("Accept", "application/json");
        req.setRequestHeader("Content-Type", "application/json; charset=utf-8");
        req.onreadystatechange = function() {
            if (this.readyState === 4) {
                req.onreadystatechange = null;
                if (this.status === 200) {
                    var results = JSON.parse(this.response);
                    if (results.value.length > 0) {
                        var entityCollectionName = results.value[0].CollectionName;
                        resolve(entityCollectionName);
                    } else {
                        reject(new Error('未找到指定实体'));
                    }
                } else {
                    reject(new Error('请求失败,状态码: ' + this.status + ', 状态信息: ' + this.statusText));
                }
            }
        };
        req.send();
    });
}

3. 额外检查项

  • 确认zzz_entity字段在Dataverse中为可编辑选项集,无表单级只读/禁用设置
  • 在表单编辑器中,确保OnLoad绑定到表单加载事件、OnChangeOfEntity绑定到zzz_entity字段的OnChange事件,且传递执行上下文作为第一个参数选项已勾选
  • 测试前清除浏览器缓存,避免旧代码残留

内容的提问来源于stack exchange,提问作者J.S.Orris

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 10:07:03