我有一个包含文件夹的列表,我正在尝试获取这些文件夹中文件总数的计数。
我设法检索包含我的文件夹的ListItemCollection。然后它开始......挑剔。
ctx
是我的ClientContext,collection
是我的ListItemCollection。
function countFiles()
{
var enumCollection = collection.getEnumerator();
while(enumCollection.moveNext())
{
currentItem = enumCollection.get_current();
var folder = currentItem.get_folder();
if (folder === 'undefined')
return;
ctx.load(folder, 'ItemCount');
ctx.executeQueryAsync(Function.createDelegate(this, function()
{
totalCount += folder.get_itemCount();
}), Function.createDelegate(this, onQueryFailed));
}
}
所以它有效......一半时间。如果我的集合中有6个项目,我会得到3或4个“属性或字段'ItemCount'尚未初始化”异常,显然我的totalCount是错误的。我似乎无法理解为什么,因为executeQueryAsync不应该在文件夹实际加载之前发生。
我对Javascript很新,所以它可能看起来很可怕,并且缺少一些我认为不值得关注的基本代码,请随时询问是否是这样。
答案 0 :(得分:1)
从异步回调引用闭包变量(在本例中为folder
)通常是一个大问题。谢天谢地,这很容易解决:
function countFiles()
{
function itemCounter(folder) {
return function() { totalCount += folder.get_itemCount(); };
}
var enumCollection = collection.getEnumerator();
while(enumCollection.moveNext())
{
var folder = enumCollection.getCurrent().get_folder();
if (folder === undefined) // not a string!
return;
ctx.load(folder, 'ItemCount');
ctx.executeQueryAsync(itemCounter(folder), Function.createDelegate(this, onQueryFailed));
}
}
(您不需要.createDelegate()
调用,因为该函数不需要this
。)
现在,在此之后,您将面临知道该计数器何时最终更新的问题。那些异步回调最终会完成,但什么时候?您可以保留一个单独的计数器,一个用于您启动的每个查询,然后在回调中减少该计数器。当它回落到零时,你就会知道你已经完成了。
答案 1 :(得分:1)
由于SP.ClientContext.executeQueryAsync
是一个 async 函数,因此很可能在第一次调用回调函数之前终止循环,因此指定代码的行为可能是意外的。
相反,我建议使用SharePoint JSOM计算文件(包括位于嵌套文件夹下的文件)的另一种更干净的方法。
以下功能允许计算列表中的列表项数:
function getItemsCount(listTitle, complete){
var ctx = SP.ClientContext.get_current();
var list = ctx.get_web().get_lists().getByTitle(listTitle);
var items = list.getItems(createQuery());
ctx.load(items);
ctx.executeQueryAsync(
function() {
complete(items.get_count());
},
function() {
complete(-1);
}
);
function createQuery()
{
var query = new SP.CamlQuery();
query.set_viewXml('<View Scope="RecursiveAll"><Query><Where><Eq><FieldRef Name="FSObjType" /><Value Type="Integer">0</Value></Eq></Where></Query></View>');
return query;
}
}
用法
getItemsCount('Documents', function(itemsCount){
console.log(String.format('Total files count in Documents library: {0}',itemsCount));
});