我一直在学习客户端对象模型,并遇到了方法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似乎对我来说非常神秘。
答案 0 :(得分:14)
首先我要说的是没有“最佳方式”,因为这些只是表现得有些不同......其次,我想补充一点,这不是SharePoint或者executeQueryAsync特定的东西,因为它通常是JS的东西。 ..
接下来我们需要理解executeQueryAsync
期望两个函数作为参数:第一个是在executeQueryAsync
成功时执行的函数,第二个是在方法遇到错误时要执行的函数。这些函数是表示发送对象的传递参数(来自executeQueryAsync
,而不是来自您的JS)以及可以包含一些数据的参数对象(args.get_message()
和args.get_stackTrace()
在这种情况下很常见失败的电话)
在“选项1”示例中,executeQueryAsync
被赋予两个匿名函数,您将无法在任何地方重复使用它们,但如果行为很简单,这可能就足够了。
在选项2中,您使用createDelegate
方法为成功和失败回调提供上下文 - 这说明了JavaScript中的范围;如果需要引用只能在调用executeQueryAsync
的函数中访问的变量,则需要使用这种模式,以便回调中的this
引用调用{{1}的函数而不是你现在所处的成功或失败函数。你可以考虑创建一个委托作为调用其他函数的调用函数,但是说'我希望该函数能够看到我能看到的内容没有无论它在代码中的位置。这可能看起来有点晦涩难懂,但这种情况在JavaScript中存在......你可以通过引用更高范围级别的变量来完全避免这样做的必要性(比如在包含调用方法的函数内部以及成功和失败方法)
选项3与选项2类似,只是它指定executeQueryAsync
或_onSucceed
函数应该是调用对象中包含的函数
Option4与选项1类似,不同之处在于您已命名函数(并且它们在当前范围内可用)并且正在按名称调用它们。
我通常使用类似选项2或选项4的内容 - 但我希望您能看到它实际上取决于您是如何构建代码的。
编辑:
回应关于_onFail
的评论 - 它似乎只是ASP.NET脚本资源中的帮助者;它只会调用Function.createDelagate()
(这是标准的JS方式 - see MDN documentation here)。它也可能在ASP.NET中的某处提供一些向后兼容性,但我不太确定!
以下是我的SP环境中脚本资源文件中的函数代码:
apply()
作为奖励,我正在考虑如何使用Function.createDelegate = function(a, b) {
return function() {
return b.apply(a, arguments)
}
};
并且我意识到我实际上更常使用它,例如选项1,使用jQuery延迟的promise模式如下:
executeQueryAsync
然后你可以做一些不那么像意大利面条的东西,比如:
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();
}
万一有人关心! :)
答案 1 :(得分:-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>