在 SharePoint 中调用“SP.ClientContext.executeQueryAsync"的最佳/首选方式 [英] Optimal/preferred way to call 'SP.ClientContext.executeQueryAsync' in SharePoint

查看:19
本文介绍了在 SharePoint 中调用“SP.ClientContext.executeQueryAsync"的最佳/首选方式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have been learning client-side object model and came across the method executeQueryAsync. I found there are quite a few ways to call this method. Some of the one I found were these:

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 有什么作用?此功能的文档 似乎是对我来说很神秘.

Which of this way is the most optimal/preferred one? Also what does the statement Function.createDelegate do? The documentation for this function seems to be very cryptic for me.

推荐答案

首先,我想说没有最佳方式",因为它们的行为都有些不同……其次,我想补充一点SharePoint 或 executeQueryAsync 特定的东西,因为它通常是 JS 的东西...

First I would say there is no 'optimal way' as these all just behave somewhat differently... Second, I would add this isn't so much a SharePoint or executeQueryAsync specific thing as it is a JS thing in general...

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

Next we need to understand that executeQueryAsync expects two functions as arguments: the first is a function to perform if executeQueryAsync succeeds, the second is a function to perform if the method encounters an error. These functions are passed parameters (from executeQueryAsync, not from your JS) representing the sending object as well as an arguments object that can have some data (args.get_message() and args.get_stackTrace() are common in the case of a failed call)

在您的选项 1"示例中,executeQueryAsync 被赋予了两个匿名函数,您将无法在任何地方重复使用它们,但如果行为很简单,这可能就足够了.

In your 'Option 1' example, executeQueryAsync is given two anonymous functions, you won't be able to re-use them anywhere, but if the behavior is simple this may be sufficient.

在选项 2 中,您使用 createDelegate 方法为成功和失败回调提供上下文——这与 JavaScript 中的作用域有关;如果您需要引用只能在调用 executeQueryAsync 的函数中访问的变量,则需要使用这种模式,以便回调中的 this 引用调用 executeQueryAsync 的函数,而不是您现在所在的成功或失败函数.您可以将创建委托视为调用其他函数的调用函数,但说我希望该函数能够看到我能看到的东西,无论它位于代码中的什么位置.这可能看起来有点神秘,但这就是 JavaScript 中的作用域......您可以通过引用更高作用域级别的变量(例如在包含调用方法以及成功和成功的函数内部)来完全规避这样做的需要失败方法)

In Option 2 you use the createDelegate method to give the success and failure callbacks a context -- this speaks to scoping within JavaScript; if you need to reference a variable that is only accessible in the function that calls executeQueryAsync, you'll need to use this sort of pattern so that this within the callback references the function that called executeQueryAsync instead of the success or failure function that you're now in. You can think of creating a delegate as the calling function calling on some other function, but saying 'I want that function to be able to see what I can see no matter where it's located at within the code.' This may all seem a bit arcane, but such is scoping within JavaScript... You could completely circumvent the need for doing this by referencing variables at higher scope levels (say inside of a function that contains the calling method as well as the success and failure methods)

选项 3 与选项 2 一样,只是它只是指定 _onSucceed_onFail 函数应该是包含在调用对象中的函数

Option 3 is just like Option 2, except it just specifies that the _onSucceed or _onFail functions should be the ones that are contained within the calling object

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

Option4 is just like Option 1, except that you've named the functions (and that they are available within the current scope) and are calling them by name.

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

I usually use something like option 2, or option 4 -- but I hope you can see that it really just depends on how you're trying to structure your code.

回应关于 Function.createDelagate() 的评论——它似乎只是 ASP.NET 脚本资源中的一个助手;除了调用 apply()(这是执行此操作的标准 JS 方式 - 在此处查看 MDN 文档).它还可能在 ASP.NET 中的某处提供一些向后兼容性,但我不太确定!

In response to a comment about Function.createDelagate() -- It seems to just be a helper in an ASP.NET script resource; it does nothing other than calling apply() (which is the standard JS way of doing this -- see MDN documentation here). It might also provide some backward compatibility somewhere within ASP.NET, but I'm not really sure!

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

Here is the code for the function from a script resource file in my SP environment:

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

作为奖励,我在考虑如何使用 executeQueryAsync 并且我意识到我实际上更频繁地使用它,就像选项 1,使用 jQuery 延迟的承诺模式如下:

And as a bonus, I was thinking about how I use executeQueryAsync and I realized that I actually use it more often like option 1, with a promise pattern using jQuery deferreds like this:

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

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

Then you can do things a little less-spaghetti-like, such as:

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

以防万一有人关心!:)

Just in case anyone cares! :)

这篇关于在 SharePoint 中调用“SP.ClientContext.executeQueryAsync"的最佳/首选方式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆