使用基于iframe的视图很难访问Dynamics 2013访问页面实体

时间:2014-09-05 09:52:02

标签: javascript angularjs dynamics-crm-2013

我正在构建一个角度应用程序,它在Dynamics 2013上作为Web资源运行。

应用程序使用一个按钮运行,该按钮使用Ribbon工作台添加到commandContainer,然后该按钮调用Xrm.Internal.openDialog

所有这一切都正常,直到我想开始使用Xrm.Page.Data

公开的实体

基本上我的按钮在动态主页面的上下文中运行,但实体位于iframe内,基于我所在的页面具有不同的Id和名称。

因此,使用简单的选择器,我无法获取其contentWindow并开始使用实体。

#crmContentPanel总是包含很少的iframe,从#contentIFrame0到#contentIFrame(n),我永远不知道哪个iframe是包含实体的iframe。

在此环境中开发应用程序的最佳实践和相关工作流程是什么?如何轻松可靠地访问包含主页面实体并使用它们的正确框架。

也许脚本位于错误的位置,需要注入主内容区域,以便直接访问正确的Xrm?我怎样才能做到这一点?

此外,一旦我最终设法访问这些数据,我怎样才能轻松地将这些数据传递给我在对话框中运行的角度应用程序,从我阅读的文档开始,该对话框只允许1个查询字符串参数,并且必须是叫数据。这对我的应用程序开始使用$routeParams来说还不够。而且我不认为使用本地或会话存储是很好的做法。在这种情况下,正确的方法是什么。

我的按钮脚本的示例代码:

function runSendSender() {

    // Content Iframe Entity data:
    var contentFrameXrm = $('#crmContentPanel')
                       .find("iframe#contentIFrame0...n")[0]
                       .contentWindow['Xrm'];

    // even if above selector was consistent across pages
    // I need to send over much more than this one Id :(
    var data = contentFrameXrm.Page.data.entity.getId();

    var src = "/WebResources/concep_/ConcepDynamicsApp/ConcepDynamicsApp.html?data=" + data;
    var DialogOptions = new Xrm.DialogOptions();
    DialogOptions.width = 800;
    DialogOptions.height = 500;
    Xrm.Internal.openDialog(src, DialogOptions, null, null, CallbackFunction);

    function CallbackFunction(returnValue) { }
}

更多细节

当我在控制台中键入以下内容时,我有时(随机)阅读表单的标题:

$('#crmContentPanel').find("iframe#contentIFrame0")[0].contentWindow['Xrm'].Page.ui.get_formTitle();

但是相关网络资源功能中的相同代码无法访问iframe和错误:

Can not Cannot read property 'contentWindow' of undefined.

为什么iframe无法通过资源脚本访问,如何访问正确的上下文和表单title / id。

2 个答案:

答案 0 :(得分:5)

我通常将以下JavaScript文件包含在需要访问CRM特定操作/信息的自定义WebResource的标题中:

<script src="ClientGlobalContext.js.aspx" type="text/javascript"></script>

这样可以访问某些非实体特定信息,例如Xrm.Page.context.getServerUrl()Xrm.Page.context.getUserId()

但是如果您在标准实体页面的顶部添加了自己的iFrame图层,那么您肯定可以使用以下构造访问当前上下文下的信息:

window.parent.Xrm.Page.data.entity.attributes.get("name").getValue();

请注意window.parent前缀。

答案 1 :(得分:3)

记录ID可以通过功能区本身作为参数发送到runSendSender。只需将相应的CrmParameterMSDN)添加到函数调用中。

在您的情况下,参数值为FirstPrimaryItemId(&#34;提供一个GUID标识符作为正在查看的记录的字符串。&#34;)

之后,您的功能会像这样改变

function runSendSender(recordId) { ... }

此外,请远离内部:要在对话框中打开Web资源,您应该使用the supported way(链接提供有关将data以外的参数传递给资源的信息。

Xrm.Utility.openWebResource(webResourceName,webResourceData,width, height)