Optimal/preferred way to call 'SP.ClientContext.executeQ

Optimal/preferred way to call 'SP.ClientContext.executeQueryAsync' in SharePoint

本文关键字:SP ClientContext executeQ call preferred way to Optimal      更新时间:2023-09-26

我一直在学习客户端对象模型,并遇到了方法executeQueryAsync。我发现有很多方法可以调用这个方法。我找到的一些是:

var context = new SP.ClientContext.get_current();
// Option 1
context.executeQueryAsync(
    function(sender, args){ },
    function(sender, args){ }
);
// Option 2
context.executeQueryAsync(
    Function.createDelegate(this, _onSucceed), 
    Function.createDelegate(this, _onFail)
);
// Option 3
context.executeQueryAsync(
    Function.createDelegate(this, this._onSucceed), 
    Function.createDelegate(this, this._onFail)
);
// Option 4
context.executeQueryAsync(_onSucceed, _onFail);

哪一种方式是最优/首选的?表述Function.createDelegate是做什么的?对于我来说,这个函数的文档似乎非常神秘。

首先我要说的是,没有"最优方法",因为这些方法的行为都有些不同……其次,我想补充的是,这不是SharePoint或executeQueryAsync特定的东西,因为它是一个一般的JS的东西…

接下来,我们需要理解executeQueryAsync期望两个函数作为参数:第一个是如果executeQueryAsync成功执行的函数,第二个是如果方法遇到错误执行的函数。这些函数传递参数(来自executeQueryAsync,而不是来自你的JS),表示发送对象,以及可以有一些数据的参数对象(args.get_message()args.get_stackTrace()在调用失败的情况下很常见)

在你的"选项1"的例子中,executeQueryAsync给出了两个匿名函数,你将无法在任何地方重用它们,但如果行为简单,这可能就足够了。

在选项2中,你使用createDelegate方法给成功和失败回调一个上下文——这说明了JavaScript中的作用域;如果需要引用一个只能在调用executeQueryAsync的函数中访问的变量,则需要使用这种模式,以便回调中的this引用调用executeQueryAsync的函数,而不是现在所处的成功或失败函数。你可以把创建一个委托看作是调用函数调用其他函数,但说"我希望那个函数能看到我能看到的东西不管它在代码中的哪个位置"这可能看起来有点神秘,但这就是JavaScript中的作用域…您可以通过在更高的作用域级别引用变量(例如在包含调用方法以及成功和失败方法的函数内部)来完全避免这样做的需要

选项3就像选项2,除了它只指定_onSucceed_onFail函数应该包含在调用对象

Option4就像选项1一样,除了您已经命名了函数(并且它们在当前作用域中可用)并按名称调用它们。

我通常使用选项2或选项4——但我希望你能看到,这实际上只是取决于你如何构建你的代码。

编辑:在回应关于Function.createDelagate()的评论——它似乎只是一个ASP的助手。. NET脚本资源;它除了调用apply()(这是标准的JS方法——参见这里的MDN文档)之外什么都不做。它还可能在ASP中提供一些向后兼容性。. NET,但我不太确定!

下面是我的SP环境中脚本资源文件中的函数代码:

Function.createDelegate = function(a, b) {
    return function() {
        return b.apply(a, arguments)
    }
};

作为奖励,我正在考虑如何使用executeQueryAsync,我意识到我实际上更经常使用它,就像选项1一样,使用jQuery延迟的承诺模式,像这样:

function getSPDataAsync(context) {
    var deferred = $.Deferred();
    context.executeQueryAsync(function(sender, args) {
        deferred.resolve(sender, args);
    }, function(sender, args) {
        deferred.reject(sender, args);
    });
    return deferred.promise();
}

然后你可以做一些不太像意大利面条的事情,比如:

...
ctx.load(items);
getSPDataAsync(ctx).then(function() {
    //do some stuff with the data when the promise resolves
});

只是以防有人关心!:)

Please try the below answer...this should help..Below code uses the context.ExecutequeryAsync method but since the items are captured separately on a string array there should not be any issues with respect to asynchronous behavior..
<style>
table { table-layout: fixed; }
td { width: 50%; }
</style><script type="text/javascript">
    function ShowselectedItems() {
        var ctx = new SP.ClientContext.get_current();
                web = ctx.get_web();
         if (ctx != undefined && ctx != null) {
            var listId = SP.ListOperation.Selection.getSelectedList();
                        var oList = ctx.get_web().get_lists().getByTitle('Testform'); // Put your list name here        
            var selectedItems = SP.ListOperation.Selection.getSelectedItems(ctx);
                        var camlquerystr = '';
                      if(selectedItems.length > 0){
                        if(selectedItems.length == 1)
                        {
                            camlquerystr += '<Where><Eq><FieldRef Name=''ID''/><Value Type=''Number''>' + selectedItems
[0].id + '</Value></Eq></Where>';
                        }
                        else if(selectedItems.length == 2)
                        {
                            camlquerystr += '<Where><Or><Eq><FieldRef Name=''ID''/><Value Type=''Number''>' + selectedItems
[0].id + '</Value></Eq><Eq><FieldRef Name=''ID''/><Value Type=''Number''>' + selectedItems[1].id + 
'</Value></Eq></Or></Where>';
                        }
                        else
                        {
                        var i;
                        camlquerystr += '<Where>';
                        for (i = 0; i < selectedItems.length - 1; i++) {
                               camlquerystr += '<Or><Eq><FieldRef Name=''ID''/><Value Type=''Number''>' + selectedItems
[i].id + '</Value></Eq>';
                        }
                        camlquerystr += '<Eq><FieldRef Name=''ID''/><Value Type=''Number''>' + selectedItems[i].id + 
'</Value></Eq>';
                        for (i = 0; i < selectedItems.length - 1; i++) {
                               camlquerystr += '</Or>';
                        }
                        camlquerystr += '</Where>';
                        }
                       }
                       else
                       {
                           alert('Please select your item');
                           retrun;
                       }
                        var camlQuery = new SP.CamlQuery();
                        camlQuery.set_viewXml('<View><Query>' + camlquerystr + '</Query></View>');
                        this.collListItem = oList.getItems(camlQuery);
                        ctx.load(collListItem, 'Include(Id, Title,Name,First_x0020_Name,Last_x0020_Name)');
                        ctx.executeQueryAsync(Function.createDelegate(this, this.success), Function.createDelegate(this, 
this.failed));
         }
       }
        function success() {
 var listItemInfo = '';
            var headstr = "<html><head><title></title></head><body>";
            var footstr = "</body>";
            var content;
    var listItemEnumerator = collListItem.getEnumerator();
    while (listItemEnumerator.moveNext()) {
        var oListItem = listItemEnumerator.get_current();
        content += "<table border='1' width='100%' style='table-layout: fixed;'><tr><td>Title:</td><td>" + oListItem.get_item('Title') + "</td></tr><tr><td>Name:</td><td>" + oListItem.get_item('Name') + "</td></tr><tr><td>First Name:</td><td>" + oListItem.get_item('First_x0020_Name') + "</td></tr><tr><td>LastName:</td><td>" + oListItem.get_item('Last_x0020_Name') + "</td></tr></table><br/><br/>";
    }
 w = window.open("", "_blank", "k");
                 w.document.write(headstr + content + footstr);
                 w.print();
        }
        function failed(sender, args) {
            alert('failed. Message:' + args.get_message());
        }        
</script><a href="#" onclick="javascript:ShowselectedItems();">Show Items</a>​​​​​