属性未初始化..但它应该是

A property not initialized... yet it should be?

本文关键字:初始化 属性      更新时间:2023-09-26

我有一个包含文件夹的列表,我正在尝试获取这些文件夹中文件总数的计数。

我设法检索到一个包含我的文件夹的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很陌生,所以它可能看起来很可怕,并且缺少一些我认为不值得感兴趣的基本代码,请随意询问是否是这样。

从异步回调中引用闭包变量(在本例中类似于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。)

现在,在那之后,您将面临知道计数器何时最终更新的问题。这些异步回调最终会结束,但什么时候呢?您可以保留一个单独的计数器,每个查询启动一个计数器,然后在回调中递减。当它降回零时,你就会知道你完了。

由于SP.ClientContext.executeQueryAsync是一个异步函数,因此循环可能会在对回调函数的第一次调用完成之前终止,因此指定代码的行为可能是意外的。

相反,我建议使用SharePointJSOM计算文件(包括位于嵌套文件夹下的文件)的另一种更干净的方法。

如何使用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));
});