Я использую плагин datatables, чтобы отобразить некоторые результаты, сложность здесь заключается в том, что мне нужно перебирать некоторые списки в Sharepoint, затем делать запрос, а затем добавлять каждый результат в конечный результат, а затем показывать этот окончательный результат.
Когда я отлаживаю foreach (результат), я вижу, что результаты добавлены, и до сих пор я получаю 13 результатов.
Однако, когда отладчик достигает метода datatable.add, тогда массив пуст, и ничего не отображается.
function GetData(billCycleId, clientCode, jobCodes, engagementCode) {
var enhanceFunctions = [
function(searchResultRow) {
return spService.AddHyperLinkOnFields(searchResultRow, config.HyperLinks);
},
function(searchResultRow) {
return spService.AddPresenceOnFields(searchResultRow, config.UserFields);
},
function(searchResultRow) {
return spService.FormatDateFields(searchResultRow, config.DateFields, generalConfig.DateTimeFormat);
},
function(searchResultRow) {
return spService.AddImageMapping(searchResultRow, config.ImageFields);
},
function(searchResultRow) {
return spService.FormatNumberFields(searchResultRow, config.NumberFields);
}
];
var selectProperties = spService.TransformFieldsToSelectProperties(config.Fields);
var extendedSelectProperties = selectProperties.slice(); // copy array
var hyperLinkedProperties = spService.TransformFieldsToSelectProperties(config.HyperLinks)
extendedSelectProperties = extendedSelectProperties.concat(hyperLinkedProperties);
spService.GetAllListsFromWeb()
.then(function(lists){
var listEnumerator = lists.getEnumerator();
var result =[];
while (listEnumerator.moveNext()) {
var oList = listEnumerator.get_current();
var title = oList.get_title();
var id = oList.get_id();
if(title.indexOf("Bill Cycles") !== -1){
// Get data from SP
GetRelatedBillCyclesFromList(id, extendedSelectProperties, billCycleId, clientCode, jobCodes, engagementCode, enhanceFunctions)
.then(function (data) {
var trimmedData = spService.SpSearchQuery.TrimSearchResultsToSelectProperties(data, selectProperties);
// Add data to dataTable
trimmedData.forEach(function(item){ // loop over source array
result.push(item); //append to result array
});
})
.catch (function (message) {
vm.Name = "Error";
vm.ValidDataLoaded = true;
});
}
//Do something with oList.
}
var dataTable = $(tableSelector).DataTable();
dataTable.clear().rows.add(result).columns.adjust().draw(); // Resize columns based on new data sizes
vm.ValidDataLoaded = true;
})
}
function getAllListsFromWeb(){
var deferred = $q.defer();
var context = SP.ClientContext.get_current();
var web = context.get_web();
var lists = web.get_lists();
context.load(lists);
context.executeQueryAsync(
function() {
$log.info("Successfully retrieved list item result");
deferred.resolve(lists);
},
function(error, errorInfo) {
$log.warn("Retrieving list item result failed");
deferred.reject(errorInfo);
}
);
return deferred.promise;
}
Обновление 1
Также попробовал это, но не работал
function GetData(billCycleId, clientCode, jobCodes, engagementCode) {
var enhanceFunctions = [
function(searchResultRow) {
return spService.AddHyperLinkOnFields(searchResultRow, config.HyperLinks);
},
function(searchResultRow) {
return spService.AddPresenceOnFields(searchResultRow, config.UserFields);
},
function(searchResultRow) {
return spService.FormatDateFields(searchResultRow, config.DateFields, generalConfig.DateTimeFormat);
},
function(searchResultRow) {
return spService.AddImageMapping(searchResultRow, config.ImageFields);
},
function(searchResultRow) {
return spService.FormatNumberFields(searchResultRow, config.NumberFields);
}
];
var selectProperties = spService.TransformFieldsToSelectProperties(config.Fields);
var extendedSelectProperties = selectProperties.slice(); // copy array
var hyperLinkedProperties = spService.TransformFieldsToSelectProperties(config.HyperLinks)
extendedSelectProperties = extendedSelectProperties.concat(hyperLinkedProperties);
var result =[];
var data = spService.GetAllListsFromWeb()
.then(function(lists){
var listEnumerator = lists.getEnumerator();
while (listEnumerator.moveNext()) {
var oList = listEnumerator.get_current();
var title = oList.get_title();
var id = oList.get_id();
if(title.indexOf("Bill Cycles") !== -1){
// Get data from SP
GetRelatedBillCyclesFromList(id, extendedSelectProperties, billCycleId, clientCode, jobCodes, engagementCode, enhanceFunctions)
.then(function (data) {
var trimmedData = spService.SpSearchQuery.TrimSearchResultsToSelectProperties(data, selectProperties);
// Add data to dataTable
trimmedData.forEach(function(item){ // loop over source array
result.push(item); //append to result array
});
})
.catch (function (message) {
vm.Name = "Error";
vm.ValidDataLoaded = true;
});
}
}
return result;
})
var resultadata = data;
var dataTable = $(tableSelector).DataTable();
dataTable.clear().rows.add(resultdata).columns.adjust().draw(); // Resize columns based on new data sizes
vm.ValidDataLoaded = true;
}
Поскольку данные, похоже, являются обещанием, вы можете попробовать следующее:
//not saving it to data
spService.GetAllListsFromWeb()
.then(function (lists) {
var listEnumerator = lists.getEnumerator();
return Promise.all(
(function(){
var promises = [];
while (listEnumerator.moveNext()) {
var oList = listEnumerator.get_current();
var title = oList.get_title();
var id = oList.get_id();
if (title.indexOf("Bill Cycles") !== -1) {
// Get data from SP !!! this is also async and returns a promise
// add the promise to promises array and wait for all to finish
// look above in Promise.all
promises.push(
GetRelatedBillCyclesFromList(
id,
extendedSelectProperties,
billCycleId,
clientCode,
jobCodes,
engagementCode,
enhanceFunctions
)
.then(function (data) {
return spService
.SpSearchQuery
.TrimSearchResultsToSelectProperties(
data,
selectProperties
);
})
);
}
}
return promises
})() //IIFE returning an array of promises
);
})
.then(
function(data){
console.log("got data:",JSON.stringify(data,undefined,2));
var resultadata = data;
var dataTable = $(tableSelector).DataTable();
dataTable.clear().rows.add(resultdata).columns.adjust().draw(); // Resize columns based on new data sizes
vm.ValidDataLoaded = true;
}
);
Вы должны действительно проверить, что такое обещание и как оно используется в JavaScript.
Поскольку функции, которые вы пишете, всегда синхронны (только один поток, выполняющий ваш код), ваши функции должны немедленно возвращать значение (не блокируя).
Когда функции необходимо выполнить сетевой запрос, файл IO или длительный процесс, вы сразу же вернете обещание. Обещание - это объект, который имеет функцию, называемую then
которая принимает 2 функции обработчика
Поэтому, когда вы пытаетесь делать такие вещи, как:
var result = [];
var later = x => new Promise(r=>setTimeout(r(x),100));
[1,2,3,4,5]
.map(
x =>
later(x)
.then(
x => {
console.log("resolved with:",x);
result.push(x);
return x;
}
)
);
console.log("first output",result);
//the output will be:
// first output []
// resolved with: 1
// resolved with: 2
// resolved with: 3
// resolved with: 4
// resolved with: 5
Вы увидите, что к тому времени, когда вы попытаетесь что-то сделать, ни одно из обещаний не будет разрешено, поэтому оно будет пустым. В ответе, который я поставил здесь, я использую Promise.all
для решения всех обещаний, а затем используйте значения разрешения для dataTable.