CRM 2013:保存后强制刷新表单

时间:2014-08-11 06:23:20

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

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

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

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

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

  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
      }
    
  3. 有人可以解释一下如何使用刷新或保存方法来强制刷新表单吗?

    拉​​杰什

8 个答案:

答案 0 :(得分:3)

对我而言,这就解决了目的(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);

答案 1 :(得分: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) {
    }
    );

答案 2 :(得分:0)

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

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

答案 3 :(得分:0)

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

  

来自MSDN

     

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

所以,你必须通过' false'这个方法(你只需要刷新,不需要保存)

答案 4 :(得分:0)

因为我无法找到完整的代码,而这些代码一般都是用#39;可重复使用的方式,这里是:

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);
}

答案 5 :(得分:0)

使用Mscrm.Utilities.reloadPage();

答案 6 :(得分:0)

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

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

答案 7 :(得分:0)

您可以通过在表单上放置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);
}

在修改后的字段上创建更改事件并提供上述功能名称。