属性未初始化..但它应该是
A property not initialized... yet it should be?
我有一个包含文件夹的列表,我正在尝试获取这些文件夹中文件总数的计数。
我设法检索到一个包含我的文件夹的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));
});
相关文章:
- ng重复中的ng模型-初始化唯一作用域属性
- 每次属性更改时,角度控制器都会初始化
- 为什么我总是得到属性或字段尚未初始化
- 在初始化Javascript时执行的私有函数中设置公共属性
- 新Javascript对象的可选初始化属性
- 在object.defineProperty之前在对象初始化中设置属性
- 想要初始化“;min”;输入类型的属性=“;日期“;在HTML5中,具有特定日期格式的日期值
- 初始化可从元素属性值观察到的Knockout
- 在使用函数作为构造函数时,我在初始化属性时卡住了这个运算符.我的代码如下
- 如何在使用 AngularJS ng-repeat 时初始化本地范围内的属性
- Javascript 对象属性初始化
- 初始化时主干不休息属性值
- Javascript:按属性初始化对象
- Vue.js从 html 初始化对象属性
- 使用同一对象的其他属性初始化对象属性
- 余烬未正确初始化存储:无法读取未定义的属性“查找”
- 在 Backbone 中将函数设置为属性.js给了我一个错误,但如果我在初始化方法中设置它,它会起作用
- 获得'未定义'在原型的构造函数中初始化属性时
- 如何在Javascript构造函数中初始化属性
- 在Javascript中第一次访问时初始化属性