从SharePoint列表

时间:2015-11-03 09:30:32

标签: javascript jquery sharepoint sharepoint-2013

现在我有一个用于从SharePoint列表中获取列表项的jQuery函数

function getListItems(listTitle, queryText){ 
    var ctx = SP.ClientContext.get_current();
    var splist =  ctx.get_web().get_lists().getByTitle(listTitle);  
    var camlQuery = new SP.CamlQuery();
    camlQuery.set_viewXml(queryText);
    var listItems = splist.getItems(camlQuery);

    ctx.load(listItems); 

    var d = $.Deferred();
    ctx.executeQueryAsync(function() {
       var result = listItems.get_data().map(function(i){
           return i.get_fieldValues();   
       });
       d.resolve(result);
    },
    function(sender,args){
       d.reject(args);
    });
    return d.promise();
}

然后我调用此函数

getListItems(listname , "").done(function(listItems){
      //do something here...
}).fail(function(error){console.log(error.get_message());}); // Error message

但其中一个列表包含相当多的记录,我想向用户显示进度,以便他们知道发生了什么。有没有办法用客户端脚本来做到这一点?任何帮助表示赞赏。谢谢。

2 个答案:

答案 0 :(得分:1)

使用提供的示例,您只能显示 indeterminate 进度条,因为请求已提交一次到服务器,并且无法确定当前状态是否已完成。

但是,由于SharePoint JSOM API支持分页数据检索,您可以考虑以下方法,以确定当前状态是否完整,从而显示确定进度条。

function getPagedListItems(list, queryText,itemsCount,position){
    itemsCount = itemsCount || 100; 
    var ctx = SP.ClientContext.get_current();
    var list =  ctx.get_web().get_lists().getByTitle(listTitle);
    var ctx = list.get_context();  
    var camlQuery = new SP.CamlQuery();
    if(typeof position != 'undefined')
        camlQuery.set_listItemCollectionPosition(position);
    var viewXml = String.format("<View>{0}<RowLimit>{1}</RowLimit></View>",queryText,itemsCount);
    camlQuery.set_viewXml(viewXml);
    var listItems = list.getItems(camlQuery);
    ctx.load(list, 'ItemCount'); 
    ctx.load(listItems); 

    var d = $.Deferred();
    ctx.executeQueryAsync(function() {
       d.resolve(listItems,list.get_itemCount());
    },
    function(sender,args){
       d.reject(args);
    });
    return d.promise();
}

function getListItems(listTitle, queryText,itemsCount,position,results){
    results = results || [];
    return getPagedListItems(listTitle, queryText,itemsCount,position)
   .then(function(pagedItems,totalItemCount){
       pagedItems.get_data().filter(function(i){
           results.push(i.get_fieldValues());   
       }); 
       var percentLoaded = results.length / totalItemCount * 100;
       console.log(String.format('{0}% has been loaded..',percentLoaded));
       var pos = pagedItems.get_listItemCollectionPosition();
       if(pos != null) {
           return getListItems(listTitle, queryText,itemsCount,pos,results);
       }    
       return results;     
   });
}

<强>用法

var listTitle = 'Contacts';
getListItems(listTitle , "",20)
.done(function(results){
     console.log('Completed');
})
.fail(function(error){
    console.log(error.get_message());
}); 

<强>结果

enter image description here

答案 1 :(得分:0)

简答:你不能

由于您的查询是作为单个请求执行的,因此无法显示“真实”进度,尽管您可以通过显示通用的“加载”gif伪造它。

长答案:如果你真的想要

,你可以

如果您要修改要分页的查询(每个查询有一个行限制),然后每页执行一个请求,直到加载所有记录,那么您可以在页面上更新一些表示进度的内容。

// Use the RowLimit element to query for only 100 items at a time
camlQuery.set_viewXml("<View>" 
    + "<OrderBy><FieldRef Name=\"Created\" /></OrderBy>"
    + "<RowLimit>100</RowLimit>"
    + "</View>"); 

现在在executeQueryAsync()的onSuccess函数中,您可以访问列表项集合的listItemCollectionPosition属性,并将其传递回CAML查询以获取下一页项目。

var itemsCount = listItems.get_count();
// use itemCount to update the current progress as displayed to the user

camlQuery.set_listItemCollectionPosition(listItems.get_listItemCollectionPosition());
// set the query's listItemCollectionPosition so you'll get the next page of results

// reload the items with the updated query
listItems = splist.getItems(camlQuery);
ctx.load(listItems);
ctx.executeQueryAsync(... // rinse and repeat to get the next batch of items

显然,这种方法需要您重构代码以允许任意数量的函数调用。您可能希望将onSuccess函数拆分为命名函数而不是匿名函数,因此可以在某种程度上递归执行。

当您重构代码时,我还建议将整个代码块包装在一个立即执行的函数表达式中,以便可以根据需要访问您的变量而不会污染全局名称空间。

(function(){
    //your code here
})();