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

Dynamics 365 WebResource:async/await处理查找字段Promise问题排查

异步过滤Dynamics 365查找字段失效问题

尝试通过async/await异步调用函数从关联实体获取记录,以过滤目标查找字段。调试时能正确获取所有值,但查找字段仍显示全部记录而非过滤结果;断点显示await addMasterContratLookupFilter(formContext);处Promise状态为pending,结果返回undefined。此前使用XrmServiceToolkit可正常工作,切换为XrmWebApi后出现该问题。


相关代码

过滤逻辑函数

async function addMasterContratLookupFilter(formContext) {
    'use strict';
    debugger;
    var mzk_subcontract = formContext.getAttribute("mzk_subcontract").getValue();
    if (mzk_subcontract !== null) {
        var mzk_subcontractId = null;

        if (mzk_subcontract !== null && mzk_subcontract.length > 0) {
            mzk_subcontractId = mzk_subcontract[0].id;
            mzk_subcontractId = mzk_subcontractId.replace(/[{}]/g, "");
        }

        var query = '<fetch>'
            + '<entity name="mzk_contractmanagement">'
            + '<attribute name="mzk_contractmanagementid" />'
            + '<attribute name="mzk_mastercontractagreement" />'
            + '<order attribute="mzk_subcontract" descending="false" />'
            + '<filter type="and">'
            + '<condition attribute="mzk_contractmanagementid" operator="eq" value="' + mzk_subcontractId + '" />'
            + '<condition attribute="statecode" operator="eq" value="0" />'
            + '<condition attribute="mzk_contracttypevalue" operator="eq" value="275380001" />'
            + '</filter>'
            + '</entity>'
            + '</fetch>';

        query = "?fetchXml=" + encodeURIComponent(query);
        try {
            const results = await Xrm.WebApi.retrieveMultipleRecords("mzk_contractmanagement", query);
            if (results.entities.length > 0) {
                var values = '';
                for (var i = 0; i < results.entities.length; i++) {
                    values += "<value>" + results.entities[i]["_mzk_mastercontractagreement_value"] + "</value>";
                }

                if (values !== '') {
                    var fetchXml = '<filter type="and">'
                        + '<condition attribute="mzk_contractmanagementid" operator="in">'
                        + values
                        + '</condition>'
                        + '</filter>';
                    formContext.getControl("mzk_mastercontractagreement").addCustomFilter(fetchXml);
                }
                else {
                    // 省略的逻辑
                }

            }
            else {
                // 省略的逻辑
            }
        } catch (error) {
            console.log(error.message);
        }
    }
}

表单加载触发函数

async function PopulateMasterContractAgreement(executionContext) {
    'use strict';

    const formContext = executionContext.getFormContext();

    if (formContext.getAttribute("mzk_subcontract") !== null && formContext.getAttribute("mzk_subcontract").getValue() !== null) {
        formContext.getControl("mzk_mastercontractagreement").addPreSearch(async function () {
            await addMasterContratLookupFilter(formContext);
        });
    }

} 

问题原因与修复方案

核心问题

  1. PreSearch事件不支持异步回调:Dynamics 365的addPreSearch方法仅支持同步执行,异步回调的Promise pending状态会导致过滤器尚未添加就已打开查找界面。
  2. 查询条件逻辑错误:原fetch查询中用mzk_contractmanagementid匹配subcontractId,逻辑完全错误,应该匹配关联字段mzk_subcontract。
  3. 过滤器属性与实体未指定:添加自定义过滤器时,未指定查找字段关联的目标实体逻辑名称,且条件属性错误(用了当前实体ID而非目标实体ID)。

修复步骤

1. 重构PreSearch事件绑定

将异步逻辑改为Promise链式调用,确保过滤器添加完成后刷新查找控件:

function PopulateMasterContractAgreement(executionContext) {
    'use strict';
    const formContext = executionContext.getFormContext();
    const masterControl = formContext.getControl("mzk_mastercontractagreement");

    // 移除重复绑定的PreSearch事件
    masterControl.removePreSearch(addMasterContratLookupFilterHandler);
    // 添加同步回调,内部处理异步逻辑
    masterControl.addPreSearch(addMasterContratLookupFilterHandler);

    function addMasterContratLookupFilterHandler() {
        addMasterContratLookupFilter(formContext)
            .then(() => masterControl.refresh())
            .catch(err => console.error(err));
    }
}

2. 修正查询与过滤器逻辑

修复fetch查询条件,同时指定过滤器关联的实体逻辑名称:

async function addMasterContratLookupFilter(formContext) {
    'use strict';
    const mzk_subcontract = formContext.getAttribute("mzk_subcontract").getValue();
    const masterControl = formContext.getControl("mzk_mastercontractagreement");
    
    // 清空旧过滤器
    masterControl.removeCustomFilter();
    
    if (!mzk_subcontract || mzk_subcontract.length === 0) {
        return Promise.resolve();
    }

    const mzk_subcontractId = mzk_subcontract[0].id.replace(/[{}]/g, "");

    // 修正查询条件:匹配关联字段mzk_subcontract而非当前实体ID
    var query = '<fetch>'
        + '<entity name="mzk_contractmanagement">'
        + '<attribute name="mzk_mastercontractagreement" />'
        + '<filter type="and">'
        + '<condition attribute="mzk_subcontract" operator="eq" value="' + mzk_subcontractId + '" />'
        + '<condition attribute="statecode" operator="eq" value="0" />'
        + '<condition attribute="mzk_contracttypevalue" operator="eq" value="275380001" />'
        + '</filter>'
        + '</entity>'
        + '</fetch>';

    query = "?fetchXml=" + encodeURIComponent(query);
    try {
        const results = await Xrm.WebApi.retrieveMultipleRecords("mzk_contractmanagement", query);
        // 提取有效目标实体ID
        const masterIds = results.entities
            .map(entity => entity["_mzk_mastercontractagreement_value"])
            .filter(id => id);
        
        if (masterIds.length > 0) {
            const values = masterIds.map(id => `<value>${id}</value>`).join('');
            // 假设mzk_mastercontractagreement关联的实体逻辑名称为mzk_contract,主键为mzk_contractid
            const fetchXml = `<filter type="and"><condition attribute="mzk_contractid" operator="in">${values}</condition></filter>`;
            // 指定关联实体逻辑名称,确保过滤器生效
            masterControl.addCustomFilter(fetchXml, "mzk_contract");
        }
        return Promise.resolve();
    } catch (error) {
        console.error(error.message);
        return Promise.reject(error);
    }
}

3. 绑定字段变更事件

在mzk_subcontract字段的OnChange事件中调用PopulateMasterContractAgreement,确保字段值变化时重新触发过滤逻辑。


内容的提问来源于stack exchange,提问作者Syed Irfan Ali Shah

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 16:48:09