CRM 2011 javascript错误 - 对象未定义,明确定义时

时间:2012-10-28 06:22:08

标签: javascript dynamics-crm-2011

在我们的云托管CRM 2011中,我在机会表单中有3个字段

  • 合同期限(查询)
  • 服务开始日期(日期和时间)
  • 服务关闭日期(日期和时间)

Default values of a new form

合同条款是名为合同条款的自定义实体的查找。这些项目如下:

All Contract Terms records

我想根据其他两个条目计算并填充服务关闭日期字段。我的合同条款和服务开始日期的OnChange事件的javascript代码如下:

function UpdateAgreementCloseDate() {
    //debugger;
    if (Xrm.Page.getAttribute("po_contractterm").getValue() != null && Xrm.Page.getAttribute("po_agreementstartdate").getValue() != null) 
        {
            //Get Months from agreement term
            var ContractTermMonths = 0;
            ContractTermMonths = Xrm.Page.getAttribute("po_contractterm").getValue()[0].keyValues.po_months.value;

            //Get Start Date
            var currentAgreementStartDate;
            currentAgreementStartDate = Xrm.Page.getAttribute("po_agreementstartdate").getValue();

            //Add contract term monthsto start date
            var AgreementCloseDate = getExpirationDate(currentAgreementStartDate, parseFloat(ContractTermMonths));

Xrm.Page.data.entity.attributes.get("po_agreementclosedate").setValue(AgreementCloseDate);
Xrm.Page.data.entity.attributes.get("po_agreementclosedate").setSubmitMode("always"); // Save the Disabled Field
        }
}


function getExpirationDate(tempdate, numberofmonths) {
    var next_month = tempdate.getMonth() + numberofmonths;
    var next_year = tempdate.getFullYear();
    if (next_month > 11) {

        if (numberofmonths > 11) {
            var extrayears = parseInt(next_month / 12);
            var remainingmonths = next_month % 12;
            next_month = remainingmonths;
            next_year = next_year + extrayears;
        }
        else {
            next_month = 0;
            next_year++;
        }
    }

    tempdate.setMonth(next_month);
    tempdate.setYear(next_year);
    return tempdate;
}

当用户填充计算所需的两个值时,代码将按预期运行。但是,如果其中一个字段(在本例中为Contract Term)在创建新记录时在javascript中分配了默认值,则当用户为服务开始日期赋值时,不会进行计算:

Calculation did not happen

在我的函数中抛出调试器允许我调试javascript,我看到问题是什么。但是,我不明白为什么这是一个问题。

Exception

当用户手动填充这两个字段时,为什么这个确切的代码会起作用,而当其中一个字段是自动填充时却不行?该错误告诉我该对象为null,但在任何一种情况下都显然不为null。当用户手动输入值时,为什么这会起作用,而当javascript代码在表单OnLoad方法中预先填充值时,为什么不会这样?

更新

抛出上述异常的行部分是访问po_months属性 - 调试器告诉我属性为null:

ContractTermMonths = Xrm.Page.getAttribute("po_contractterm").getValue()[0].keyValues.po_months

2 个答案:

答案 0 :(得分:3)

我认为错误很简单:Xrm.Page.getAttribute("po_contractterm").getValue()[0].keyValues没有属性po_monthsXrm.Page.getAttribute("po_contractterm").getValue()[0].keyValues.po_months === null

您的代码在一行中浏览了很多属性。如果你不能保证每一个属性都存在某些东西,你就会遇到麻烦。

由于我认为你仍然有点困惑,所以在错误行之前设置一个断点,并查看以下所有可能表达式中的失败。

Xrm.Page.getAttribute("po_contractterm").getValue()  //this shouldn't be null
Xrm.Page.getAttribute("po_contractterm").getValue()[0]
Xrm.Page.getAttribute("po_contractterm").getValue()[0].keyValues
Xrm.Page.getAttribute("po_contractterm").getValue()[0].keyValues.po_months  //this probably doesn't exist or is null.
Xrm.Page.getAttribute("po_contractterm").getValue()[0].keyValues.po_months.value

我们可以删除检查表达式Xrm.Page.getAttribute("po_contractterm").getValue()的一部分,因为该部分在if中进行了测试。但是,检查它只是为了保持你的理智并不会有害,并且使用Visual Studio调试器,我认为你应该能够点击导航这些中的每一个,除非对象太大。知道调试器是否对你说谎也很有用,因为你的一些评论似乎表明你相信。调试器偶尔谎言,或者(更经常地)非常迟钝地呈现信息。

这是你不能懒惰的事情。好吧,也许如果你使用类似JSONPath的东西,你可能有点懒惰,但是否则,如果你不打算使用这样的工具,请确保你的路径存在需要它,或者在部分可能不存在的情况下进行适当的测试。

答案 1 :(得分:3)

我想我现在明白这个问题了。

简而言之:您假设查找字段可以访问查找记录的字段。这是不正确的。

为了扩展它,让我们从Crm实际上在查找字段中提供的内容开始。

如果您查看MSDN here。我们可以看到,当对lookup属性执行getValue()时,我们返回一个包含三个字符串属性的数组。

  

的EntityType       字符串:查找中显示的实体名称

     

ID       String:查找中显示的记录的GUID值的字符串表示形式。

     

名       String:表示要在查找中显示的记录的文本。

注意事项:

没有keyValues属性(我不知道你从哪里得到这个 - 请告诉我,如果我在这里遗漏了什么)。

除名称字段外,我们没有任何其他记录数据。例如:如果这是对联系人的查询,我们可以告诉其全名(来自姓名属性),但不能告诉其地址或电话号码。

因此,总结一下当Crm设置查找时它失败的原因是因为它只提供上面的信息,它不会填充keyValues或查找记录中的任何字段,例如: po_months

我猜测设置查找时它的工作原理,是因为你在代码中的其他地方创建了keyValues属性。

如果您需要通过查找来自相关记录的信息,则必须执行webservice调用以获取该信息 - 使用查找中的id。