【问题标题】:CRM 2013: Force refresh a form after saveCRM 2013:保存后强制刷新表单
【发布时间】:2014-08-11 06:23:19
【问题描述】:

我们需要在保存后刷新表单(以确保某些隐藏/显示逻辑根据字段值按预期工作)。

目前表单在保存记录后不会自动刷新。

我浏览了一些文章并找到了这个参考: http://msdn.microsoft.com/en-us/library/dn481607%28v=crm.6%29.aspx

当我尝试执行以下任一操作时,它会导致无限循环并引发“Callstack超出最大限制”错误。

  1. OnSave(context)
    {
      //my logic 
      ...
      ...
    
      Xrm.Page.data.save.then(SuccessOnSave, ErrorOnSave);
    }
    
      function SuccessOnSave()
     {
      //force refresh
       Xrm.Page.data.refresh();
     }
      function ErrorOnSave()
      {
        //do nothing
      }
    
  2.   OnSave(context)
     {
       ...
      ...
      //force refresh
      Xrm.Page.data.refresh(true).then(SuccessOnSave, ErrorOnSave);
    }
    
      function SuccessOnSave()
     {
      //do nothing
     }
      function ErrorOnSave()
      {
        //do nothing
      }
    

有人可以解释一下如何使用刷新或保存方法来强制刷新表单吗?

拉杰什

【问题讨论】:

标签: javascript dynamics-crm dynamics-crm-2013


【解决方案1】:

我用下面的代码来实现它

 Xrm.Page.data.save().then(
    function () {
        Xrm.Page.data.entity.attributes.forEach(function (attribute, index) {
            attribute.setSubmitMode("never");
        });
        Xrm.Utility.openEntityForm(Xrm.Page.data.entity.getEntityName(), Xrm.Page.data.entity.getId());
    },
    function (errorCode, message) {
    }
    );

【讨论】:

  • MaKeer - 我应该把这段代码放在哪里?它是如何被调用的?请帮忙。
  • 随心所欲,使用更新版本的动态,它是 executionContext.getFormContext().data.save...
【解决方案2】:

对我来说,这就是解决目标的原因(CRM 2015)

// Save the current record to prevent messages about unsaved changes
Xrm.Page.data.entity.save();

setTimeout(function () { 
    // Call the Open Entity Form method and pass through the current entity name and ID to force CRM to reload the record
    Xrm.Utility.openEntityForm(Xrm.Page.data.entity.getEntityName(), Xrm.Page.data.entity.getId()); 
}, 3000);

【讨论】:

  • Xrm.Page.data.refresh() 不是 100% ...感谢代码最好
  • 我希望 Xrm.Page.data.save().then(successCallback, errorCallback) 实际上做了SDK says it does... 的操作,但回调对我不起作用。我想这就是 CRM 2015 vanilla 和 CRM 2015 SP1 之间的区别?
【解决方案3】:

如果您想对表单数据进行硬刷新,您可能需要重新加载位置。我过去所做的是将刷新逻辑放在加载表单时(保存后)调用的函数中。棘手的部分是如果表单在 CRM 2013 中自动保存,则可以调用该函数。您还需要考虑到您不想在第一次加载时刷新表单,因为这会导致无限的重新加载循环。这是一个例子:

var formLoaded = false;
function formLoad() {
    if (formLoaded) {
        window.location = location.href;
    }
    formLoaded = true;
}

【讨论】:

    【解决方案4】:

    您已将 OnSave() 方法附加到 OnSave 事件。因此,从逻辑上讲,如果您在同一事件中再次调用 save ,则调用会递归进行。

    来自 MSDN

    Xrm.Page.data.refresh(save).then(successCallback, errorCallback); 参数:save - 一个布尔值,指示是否应保存数据 刷新后。

    所以,你必须将'false'传递给这个方法(你只需要刷新,不需要保存)

    【讨论】:

    • :-) 刚刚意识到这是一个有年头的问题
    • 这不是一岁的问题.. 它只是一个月大:)。关于您的回答,使用 false 调用“刷新”方法会给我一个弹出窗口,说“您的更改尚未保存。您确定要离开该页面吗?” ...因为我们发送的是“假”。
    【解决方案5】:

    由于我找不到以“通用”可重用方式编写的完整代码,因此如下:

    var triggeredSave = false;
    //Attach the OnSave Form event to this OnSave function  
    //and select passing of context as the first parameter.
    //Could instead be attached programmatically using the code:
    //Xrm.Page.data.entity.addOnSave(OnSave);
    function OnSave(context) {
        var eventArgs = context.getEventArgs();
        var preventedAutoSave = false;
    
        //Preventing auto-save is optional; remove or comment this line if not required.
        preventedAutoSave = PreventAutoSave(eventArgs);
    
        //In order to setup an after save event function, explicitly
        //invoke the save method with callback options.
        //As this is already executing within the OnSave event, use Boolean,
        //triggeredSave, to prevent an infinite save loop.
        if (!preventedAutoSave && !triggeredSave) {
            triggeredSave = true;
            Xrm.Page.data.save().then(
                function () {
                    //As the form does not automatically reload after a save,
                    //set the save controlling Boolean, triggeredSave, back to
                    //false to allow 'callback hookup' in any subsequent save.
                    triggeredSave = false;
                    OnSuccessfulSave();
                },
                function (errorCode, message) {
                    triggeredSave = false;
                    //OPTIONAL TODO: Response to failed save.
                });
        }
    }
    
    function PreventAutoSave(eventArgs) {
        if (eventArgs.getSaveMode() == 70 || eventArgs.getSaveMode() == 2) {
            eventArgs.preventDefault();
            return true;
        }
        return false;
    }
    
    //Function OnSuccessfulSave is invoked AFTER a save has been committed.
    function OnSuccessfulSave() {
        //It seems CRM doesn't always clear the IsFormDirty state 
        //by the point callback is executed, so do it explicitly.
        Xrm.Page.data.setFormDirty(false);
    
        //TODO: WHATEVER POST SAVE PROCESSING YOU REQUIRE
        //e.g. reload the form as per pre CRM 2013 behaviour.
        ReloadForm(false);
    
        //One scenario this post save event is useful for is retriggering
        //Business Rules utilising a field which is not submitted during save.
        //For example, if you implement a Current User field populated on Form 
        //Load, this can be used for user comparison Business Rules but you 
        //may not wish to persist this field and hence you may set its submit
        //mode to 'never'.
        //CRM's internal retriggering of Business Rules post save doesn't
        //consider changes in fields not submitted so rules utilising them may
        //not be automatically re-evaluated or may be re-evaluated incorrectly.
    }
    
    function ReloadForm(preventSavePrompt) {
        if (preventSavePrompt) {
            Xrm.Page.data.entity.attributes.forEach(function (attribute, index) {
                attribute.setSubmitMode("never");
            });
            Xrm.Page.data.setFormDirty(false);
        }
    
        Xrm.Utility.openEntityForm(Xrm.Page.data.entity.getEntityName(),
                                   Xrm.Page.data.entity.getId());
        //Another way of trying Form reload is:
        //window.location.reload(true);
    }
    

    【讨论】:

    • 使用这个,保存会被调用两次......(第一次创建对象时)
    • 似乎较新版本的动态阻止了这种形式的内部保存,错误代码为 -1 和消息“服务忙”,因为他们认为这是无限循环:/
    【解决方案6】:

    使用 Mscrm.Utilities.reloadPage();

    【讨论】:

      【解决方案7】:

      我发现this post 有助于展示Xrm.Page.data.refresh()Xrm.Utility.openEntityForm(entityName, id) 之间的区别。

      TL;DR - 如果您希望重新绘制屏幕,​​请考虑使用 Xrm.Utility.openEntityForm(entityName, id)

      【讨论】:

        【解决方案8】:

        您可以通过在表单上放置 Modified On 字段来实现。并将默认属性设置为 false。

        使用下面的JS刷新表单

        function refreshCRMFORM()
        {
        setTimeout(function () { 
            // Call the Open Entity Form method and pass through the current entity name and ID to force CRM to reload the record
            Xrm.Utility.openEntityForm(Xrm.Page.data.entity.getEntityName(), Xrm.Page.data.entity.getId()); 
        }, 1000);
        }
        

        在已修改字段上创建 On Change 事件并提供上述函数名称。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-09-17
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多