【问题标题】:ECMAScript Callback method executed after PreSaveAction method在 PreSaveAction 方法之后执行的 ECMAScript 回调方法
【发布时间】:2016-07-15 20:11:11
【问题描述】:

我的要求是从另一个列表中获取值并将其设置为 SharePoint 列表表单,然后保存该项目。

我编写了 ECMAScript 和 PreSaveAction()。但是,PreSaveAction() return true 是在 ECMAScript 回调方法之前执行的,这就是为什么当我单击 Save 按钮时我的字段值没有保存的原因。请注意,我的回调函数没有错误,并且我在警报中得到了正确的值。我不知道我在哪里做错了。以下是我的代码供您参考。

function PreSaveAction() 
    { 
        ExecuteOrDelayUntilScriptLoaded(GetTotalAmtAlloted, "sp.js");
        return true;**//This line will execute before my callback function onListItemsLoadSuccess or onQueryFailed execute. Because of this, my field value not able to save it.**

    }


 function GetTotalAmtAlloted()
    {
        var clientContext = null;
        var web = null;
        var vID;

        clientContext = new SP.ClientContext.get_current();
        web = clientContext.get_web();
        var list = web.get_lists().getByTitle("Investment");
        var camlQuery = new SP.CamlQuery();

        var q = "<View><Query><Where><Eq><FieldRef Name='InvestmentSubject' /><Value Type='Text'>abc</Value></Eq></Where></Query></View>";

        camlQuery.set_viewXml(q);

        listItems = list.getItems(camlQuery);

        clientContext.load(listItems);
        clientContext.executeQueryAsync(onListItemsLoadSuccess,onQueryFailed);//After this line "return true" in PreSaveAction() will execute and then CallBackMethods will run.

}

function onListItemsLoadSuccess(sender, args) 
{
  $("input[Title='Total Amount']").val("1000");

}

 function onQueryFailed(sender,args)
 {
  alert("error");
 }

【问题讨论】:

  • 它应该立即返回true,因为第一行只是注册了一个事件处理程序,所以那里没有错。你为什么使用ExecuteOrDelayUntilScriptLoaded?当您单击保存按钮时,我确定 SP.js 已经加载。请澄清您的问题,即您试图实现的目标,因为您现在所拥有的并没有那么大的意义。
  • 嗨,Daniel,当我的 NewForm.aspx 打开时,用户从下拉列表中选择“投资类型”。用户单击保存按钮。现在,在 PreSaveAction() 中,我将根据用户选择的“投资类型”从另一个列表中获取“总金额”隐藏字段的值。单击保存后,此“总金额”字段也应保存。但是,我的回调方法实际上从另一个列表中获取值在 PreSaveAction() 中的“return true”之后执行。
  • JavaScript 是同步的。当您从另一个列表中获取数据时,您将执行 异步 操作。如果您想在return true 之前完成它,您必须以另一种方式处理它。这就是你想要达到的目标吗?
  • 是的,丹尼尔。我正在努力实现您所提到的。你能告诉我处理它的方法吗?
  • 我提出的答案成功了吗?

标签: javascript sharepoint


【解决方案1】:

您正在执行异步函数调用,但希望它同步运行。相反,您必须等待异步函数完成,然后您的 PreSaveAction 才能返回 true

由于您使用的是 jQuery,因此可以使用 jQuery 提供的 deferred/promise 轻松实现。

function PreSaveAction() { 
    //Get the promise from the function
    var promise = GetTotalAmtAlloted();

    //This is run when the promise is resolved
    promise.done(function(){
        return true;
    });

    //This is run when the promise is rejected
    promise.fail(funtion(){

    });
}


function GetTotalAmtAlloted() {
    var d = $.Deferred();

    var clientContext = null;
    var web = null;
    var vID;

    clientContext = new SP.ClientContext.get_current();
    web = clientContext.get_web();
    var list = web.get_lists().getByTitle("Investment");
    var camlQuery = new SP.CamlQuery();

    var q = "<View><Query><Where><Eq><FieldRef Name='InvestmentSubject' /><Value Type='Text'>abc</Value></Eq></Where></Query></View>";

    camlQuery.set_viewXml(q);

    listItems = list.getItems(camlQuery);

    //An object to pass to the success and failure handlers
    var data = {d: d, list: listItems}
    clientContext.load(listItems);

    //Execute the query and pass the data with our deferred object
    clientContext.executeQueryAsync(Function.createDelegate(data, onListItemsLoadSuccess), Function.createDelegate(data, onQueryFailed));//After this line "return true" in PreSaveAction() will execute and then CallBackMethods will run.

    //Return a promise that can either resolve or reject depending on if the async function is a success or failure
    return d.promise();    
}

function onListItemsLoadSuccess() {
    //Access the listItems
    var listItems = this.list;

    //Do something with the list items

    //On success, resolve the promise
    this.d.resolve();
}

function onQueryFailed() {
    //On failure, reject the promise
    this.d.reject("Something went wrong!");
    alert("error");
}

【讨论】:

  • 这是错误的。 promise.done(function(){ return true; }); 只会结束内部函数,而不是 PreSaveAction。
  • 怎么回事? return true; 相当于将 true 值包装在承诺的 resolve 中。它将结束函数。
  • 它将结束 pormise 解析函数,将真正的解析传递到链中,但这永远不会返回到调用函数,这里是 PreSaveAction。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-04-24
  • 2023-03-12
  • 2017-02-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多