【问题标题】:Optimal/preferred way to call 'SP.ClientContext.executeQueryAsync' in SharePoint在 SharePoint 中调用“SP.ClientContext.executeQueryAsync”的最佳/首选方式
【发布时间】:2014-09-12 06:05:38
【问题描述】:

我一直在学习客户端对象模型,偶然发现了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 的声明是做什么的? documentation for this function 对我来说似乎很神秘。

【问题讨论】:

    标签: javascript sharepoint sharepoint-2013 sharepoint-clientobject


    【解决方案1】:

    首先我会说没有“最佳方式”,因为它们的行为都略有不同……其次,我要补充的是,这与其说是 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 函数应该是调用对象中包含的函数

    选项 4 与选项 1 类似,不同之处在于您已命名函数(并且它们在当前范围内可用)并按名称调用它们。

    我通常使用选项 2 或选项 4 之类的东西——但我希望您能看到它实际上取决于您尝试如何构建代码。

    编辑: 回应关于Function.createDelagate() 的评论——它似乎只是一个ASP.NET 脚本资源中的助手;除了调用apply()(这是执行此操作的标准JS 方式——see MDN documentation here)之外,它什么也不做。它还可能在 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
    });
    

    以防万一有人关心! :)

    【讨论】:

    • 美丽的解释约翰。谢谢!还有一件事。 Function.createDelegate 声明似乎来自 SharePoint,因为我找不到任何官方文档。我说的对吗?
    • Naveen,它似乎只是一个来自 ASP.NET 脚本资源的助手——我已经更新了我的答案以包含更多关于它的信息。 Function.createDelegate 不在 JS 的任何原生实现中。
    • jQuery Deferred 在这里确实有帮助。我做同样的事情。
    【解决方案2】:
    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>​​​​​
    

    【讨论】:

    猜你喜欢
    • 2011-12-30
    • 1970-01-01
    • 2021-03-12
    • 1970-01-01
    • 2011-05-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多