如何在 Dynamics 365 9.0 的 Ribbon 命令中获取 formContext

How to get formContext in Ribbon command of Dynamics 365 9.0

在 Dynamics 365 9.0 中,关于如何访问表单属性和控件有相当大的变化 - 我们应该将 executionContext 传递给函数并获取 [=13= 而不是 Xrm.Page 命名空间] 使用 getFormContext() 函数。这工作正常,我使用这种方法从来没有问题。

但是我还没有想出如何在从 Ribbon 调用的函数中正确访问 formContext。文档说这应该非常简单:

https://docs.microsoft.com/en-us/dynamics365/customer-engagement/developer/customize-dev/pass-dynamics-365-data-page-parameter-ribbon-actions

function myFunction(executionContext) {
    var formContext = executionContext.getFormContext();
    var focusFieldValue = formContext.ui.controls.get(PrimaryControlId).getAttribute().getValue();
}

但是没有说明如何将executionContext传给Ribbon函数。在普通功能中有一个复选框 "Pass execution context as first parameter" 但是功能区功能呢?我们可以将一些参数传递给这些函数,但它们只是所选记录的 GUID,或者所选记录的类型,甚至是对象列表,但我在文档中找不到,如果有一个参数等于 executionContext.有人已经解决了这个问题吗?

我也知道我可以使用 Xrm.Page 并且它会起作用(至少现在......)但我想知道如何使用 9.0 版中的最新指南来完成它

更新 1:

根据 Scott 的建议和 this article 我将 PrimaryControl 传递给了我的 Ribbon 命令,但不幸的是,参数是 Mscrm.FormControlLite 类型并且它没有 getAttribute 函数或任何函数将允许访问 formContext(至少我没有看到任何有用的东西)。开发者工具的一些截图:

所以它看起来像是某种形式的表示形式,但可能与 formContext 无关(我假设如果要从记录列表中调用功能区,则该项目可以是网格类型或类似的类型那)

按照 https://docs.microsoft.com/en-us/dynamics365/get-started/whats-new/customer-engagement/important-changes-coming#some-client-apis-are-deprecated 将其作为 PrimaryControl 参数传递。

因此,如果您将 PrimaryControl 作为第二个参数传递给这样的命令函数,您可以使用

arguments[1].getAttribute(…)

我也遇到了同样的问题。我发现的是,Microsoft doco 出错了。请按照 Scott 提到的从功能区命令操作传递 CRM 参数的任何内容进行操作。 在 javascript 函数中,请尝试以下获取表单上下文

var formContext = primaryControl.getFormContext();

这解决了我的问题。

按照@scott-durow 的建议传递 primaryControl 后,最好不要使用 primaryControl.getFormContext() 而是像使用 formContext 一样使用 primaryControl。

根据文档 (1/2/2019):https://docs.microsoft.com/en-us/dynamics365/customer-engagement/developer/customize-dev/pass-dynamics-365-data-page-parameter-ribbon-actions#form-and-grid-context-in-ribbon-actions,应该像 formContext 一样对 primaryControl 执行操作。

function mySampleFunction(primaryControl) {
    var formContext = primaryControl;
    // Perform operations using the formContext object
}

但是,所提供示例的关键部分是:// 使用 formContext 对象执行操作 作为关键(不知道他们为什么添加 var formContext = primaryControl 行, imo, 如果他们只是展示一个例子会更清楚: primaryControl.getAttribute('xxxx');

我怀疑 primaryControl.getFormContext() 代码开始被使用,因为这就是您在使用表单时获取 formContext 的方式 (https://docs.microsoft.com/en-us/dynamics365/customer-engagement/developer/clientapi/clientapi-form-context#using-the-formcontext-object-instead-of-the-xrmpage-object)。

使用 primaryControl.getFormContext() 的问题在于它可以与普通的 Web 界面一起使用,但会破坏 UCI。但是,如果您将 primaryControl 当作表单上下文来使用,那么它适用于旧版 Web 客户端和 uci 界面。

这是我使用的函数:

function getFormContext(executionContext) {
     var formContext = null;
     if (executionContext !== null) {
         if (typeof executionContext.getAttribute === 'function') {
             formContext = executionContext; //most likely called from the ribbon.
         } else if (typeof executionContext.getFormContext === 'function' 
                 && typeof(executionContext.getFormContext()).getAttribute === 'function') {
            formContext = executionContext.getFormContext(); // most likely called from the form via a handler
         } else {
            throw 'formContext was not found'; //you could do formContext = Xrm.Page; if you like.
        }
    }
    return formContext;
}

您可以使用一个小技巧来不必将主控件作为 Crm 参数传递给 RibbonWorkbench 实用程序,或者如果这样做了,它不会为您工作,因为如果您是在家庭网格丝带中尝试这个。

var context=Xrm.Utility.getGlobalContext();

我希望这对你或其他人有用。