我对一个返回一些数据的sharepoint列表进行了查询,但是对于每个项目,我必须进行另一个查询以获取其文档类型(内容类型),问题是这部分代码是在页面已经呈现。
var cname = getContentTypeOfCurrentItem(listItemValues['ID'].toString());
listItemsWithValues['Document Type'] = cname;
function GetRelatedBillingDocumentsFromList(selectProperties, currentBillCyclePath, clientCode, jobCodes, engagementCode, enhanceFunctions) {
$log.info('Retrieving related billing documents for bill cycle with name [' + currentBillCyclePath + ']');
var deferred = $q.defer();
var webUrl = _spPageContextInfo.webAbsoluteUrl;
var viewFields = spService.ConvertSelectPropertiesToViewFields(selectProperties);
// query must return the documents for the same client but in other bill cycles not the current one
var camlQuery = '<View Scope="RecursiveAll">' + viewFields +
'<Query>' +
'<Where>' +
'<And>' +
'<Eq>' +
'<FieldRef Name="ClientCode" />' +
'<Value Type="Text">' + clientCode + '</Value>' +
'</Eq>' +
'<Neq>' +
'<FieldRef Name="ContentType" />' +
'<Value Type="Computed">Bill Cycle</Value>' +
'</Neq>' +
'</And>' +
'</Where>' +
'</Query>' +
'</View>';
var billCyclesListId = '{c23bbae4-34f7-494c-8f67-acece3ba60da}';
spService.GetListItems(billCyclesListId, camlQuery, selectProperties)
.then(function (listItems) {
var listItemsWithValues = [];
if (listItems) {
var enumerator = listItems.getEnumerator();
var promises = [];
while (enumerator.moveNext()) {
var listItem = enumerator.get_current();
var listItemValues = [];
selectProperties
.forEach(function (propertyName) {
var value = listItem.get_item(propertyName);
if (propertyName === 'PwC_JobCodesMulti') {
jobvalue = '';
value.forEach(function (jobvalues) {
jobvalue += jobvalues.get_lookupValue() + ';';
});
listItemValues[propertyName] = jobvalue;
} else {
listItemValues[propertyName] = value;
}
//listItemValues[propertyName] = value;
});
listItemsWithValues.push(listItemValues);
}
var cname = getContentTypeOfCurrentItem(listItemValues['ID'].toString());
listItemsWithValues['Document Type'] = cname;
}
listItemsWithValues.forEach(function (listItem) {
var fileDirRef = listItem['FileRef'];
var id = listItem['ID'];
var title = listItem['Title'];
var serverUrl = _spPageContextInfo.webAbsoluteUrl.replace(_spPageContextInfo.webServerRelativeUrl, '');
var dispFormUrl = serverUrl + '/sites/billing/_layouts/15/DocSetHome.aspx?id=' + fileDirRef;
//listItem["FileRef"] = dispFormUrl;
//listItem["Bill Cycle"] = dispFormUrl;
var parentLink = listItem['FileRef'];
arrayofstrings = parentLink.split('/');
var billCycleFolderName = arrayofstrings[arrayofstrings.length - 2];
arrayofstrings.pop();
var hyperLink = '<a href="' + arrayofstrings.join('/') + '">' + billCycleFolderName + '</a>';
listItem['Bill Cycle'] = hyperLink;
});
var enhancedListItemValues = spService.SpSearchQuery.EnhanceSearchResults(listItemsWithValues, enhanceFunctions);
deferred.resolve(listItemsWithValues);
})
.catch(function (message) {
deferred.reject();
});
return deferred.promise;
}
function getContentTypeOfCurrentItem(id) {
var clientContext = new SP.ClientContext.get_current();
var oList = clientContext.get_web().get_lists().getByTitle('Bill Cycles');
listItem = oList.getItemById(id);
clientContext.load(listItem);
listContentTypes = oList.get_contentTypes();
clientContext.load(listContentTypes);
clientContext.executeQueryAsync(
Function.createDelegate(this, getContentTypeOfCurrentItemSucceeded),
function (error, errorInfo) {
$log.warn('Retrieving list item result failed');
deferred.reject(errorInfo);
}
);
}
function getContentTypeOfCurrentItemSucceeded(sender, args) {
var ctid = listItem.get_item('ContentTypeId').toString();
var ct_enumerator = listContentTypes.getEnumerator();
while (ct_enumerator.moveNext()) {
var ct = ct_enumerator.get_current();
if (ct.get_id().toString() == ctid) {
var contentTypeName = ct.get_name();
return contentTypeName;
}
}
}
我如何在此承诺确保内容类型调用正确完成?
答案 0 :(得分:2)
I've refactored your example to understand the intent of your code. I think that you need to understand better the async nature of promises and the idea of scope / closures (I don't think your code works at all, in many ways, i've included a review in the oldscript.js
file).
https://embed.plnkr.co/3YcHZzxH4u6ylcA2lJZl/
My example uses a Stub object to simulate your provider, but to keep it short I'd say: the key is Promise.all
, a factory that generates a new Promise that gets fulfilled when all the promises are resolved.
You need to store one promise for each item holding the future value for each ID (your original snippet only stores the last ID, it seemed to be a bug), and when all of them are resolved you can keep working with your data (later on time, aka async or deferred).
Hope it helps
A relevant snippet...
function addContentType(listItem){
var promise = getContentTypeOfCurrentItem(listItem.ID.toString());
promise.then(function(cname){
listItem['Document Type'] = cname;
});
return promise;
}
function processListItems(listItems) {
var listItemsWithValues = listItems.map(listItemToValue);
var promises = listItemsWithValues.map(addContentType);
Promise.all(promises).then(youCanUseTheData);
function youCanUseTheData(){
/*
At this point, each listItem holds the 'Document Type' info
*/
listItemsWithValues.forEach(function (listItem) {
console.log(listItem);
});
}