2016-09-22 3 views
0

Это своего рода неловкий вопрос, но я застрял. Мой фон управляется кодом, и я никогда не изучал JavaScript, но все же я хочу реализовать крошечный проект. Сценарий работает в SharePoint 2010, запрашивает элементы из пользовательского списка с использованием объектной модели JavaScript и заполняет диаграмму или таблицу Google соответственно. С помощью MSDN и Google Developer Мне удалось запросить данные из одного списка и визуализировать его.JavaScript code design async/callback

Однако я не могу передать концепцию для запроса нескольких списков, объединить результирующие наборы и, наконец, перейти к API Google. В моем коде я создал цепочку обратных вызовов, например showChart-> loadListData-> drawChart. Это плохой дизайн, поскольку он негибкий и не может быть расширен. Все методы API являются асинхронными и не имеют возвращаемых значений, но ожидают, что имена методов будут вызваны после завершения. Это то, что меня застряло, и где мне не хватает знаний.

Я очень рад за каждый комментарий и ответ, также могу предоставить фактический исходный код, если потребуется. Спасибо заранее, Тоби

UPDATE, как просили на @Utkanos:

var listItems; 
$(document).ready(function() {  
    ExecuteOrDelayUntilScriptLoaded(loadChartData, "sp.js"); 
}); 
function loadChartData() { 
    var camlQuery = SP.CamlQuery.createAllItemsQuery(); 
    camlQuery.set_viewXml("<View><Query><Where><Eq><FieldRef Name='Year'/><Value Type='Text'>2015</Value></Eq></Where></Query></View>"); 
    loadListData('CustomList', camlQuery, drawChart, readListItemFailed); 
} 
function loadListData(listTitle, camlQuery, onSuccess, onFail) { 
    context = SP.ClientContext.get_current(); 
    var list = context.get_web().get_lists().getByTitle(listTitle); 
    var listItems = list.getItems(camlQuery); 
    context.load(listItems); 
    context.executeQueryAsync(function(sender, args){onSuccess(listItems);}, onFail); 
} 
function drawDpOverviewChart(listItems) { 
    var data; 
    var enumerator = listItems.getEnumerator(); 
    data = new google.visualization.DataTable(); 
    data.addColumn('string', 'Column1'); 
    data.addColumn('number', 'Column2'); 
    var listItem; 
    while (enumerator.moveNext()) { 
      listItem = enumerator.get_current(); 
      data.addRow([listItem.get_item('Title'), Math.round(listItem.get_item('Balance')/10000)/100]); 
    } 
    var options = {'title':'Pretty Chart'}; 
    var chart = new google.visualization.PieChart(document.getElementById('chart_div')); 
    chart.draw(data, options); 
} 
function readListItemFailed(sender, args) { 
    alert('Request failed. ' + args.get_message() + '\n' + args.get_stackTrace()); 
} 
+0

Пожалуйста, ваши код. – Utkanos

+0

Возможный дубликат [Как подождать набора асинхронных функций обратного вызова?] (Http://stackoverflow.com/questions/10004112/how-can-i-wait-for-set-of-asynchronous-callback-functions) – JJJ

+0

, если у вас есть поля поиска друг к другу, вы можете использовать [REST API] (https://msdn.microsoft.com/en-us/library/ff798339.aspx), чтобы «присоединить» их к одному вызову ... – WhiteHat

ответ

0

при использовании SP 2010 на типовой странице .aspx, у вас есть некоторые инструменты доступны,

, такие как MicrosoftAjax.js и _spPageContextInfo

с помощью REST API, вы можете присоединиться списки на подстановок полей и включают в себя поля из обоих списков в одном запросе

Ниже приведен пример URL для вызова на отдых ...

'/_vti_bin/ListData.svc/MI_Projects?$expand=ModifiedBy&$filter=ModifiedBy/Id eq 738'

этот вызов фактически «присоединяется» список MI_Projects к UserInformationList путем «расширения» ModifiedBy

так, когда возвращает данные , вы можете получить доступ к любому из полей информации о пользователе, т.е.
row.ModifiedBy.Name

это можно сделать с помощью подстановок полей на пользовательские списки, а также

, чтобы сделать звонок, вы можете использовать Sys.Net.WebRequest класс от MicrosoftAjax
этот класс также позволяет передавать переменные в функцию обратного вызова

см следующий фрагмент кода ...

function makeCall() { 

    // Sys.Net.WebRequest is from MicrosoftAjax.js 
    var webRequest = new Sys.Net.WebRequest(); 
    webRequest.get_headers()['Cache-Control'] = 'no-cache'; 
    webRequest.get_headers()['Accept'] = 'application/json'; 
    webRequest.get_headers()['Content-Type'] = 'application/json'; 
    webRequest.set_url(_spPageContextInfo.webServerRelativeUrl + '/_vti_bin/ListData.svc/MI_Projects?$expand=ModifiedBy&$filter=ModifiedBy/Id%20eq%20738'); 

    // use the 'user context' to pass variables you want available in the callback 
    webRequest.set_userContext({ 
    Title: 'variable to pass to completed callback' 
    }); 
    webRequest.add_completed(restComplete); 
    webRequest.invoke(); 

} 

// the first argument of callback is the Sys.Net.WebRequestExecutor class 
function restComplete(executor, eventArgs) { 
    if (executor.get_responseAvailable()) { 
    if (executor.get_statusCode() === 200) { 

     // get variable passed via user context 
     var variablePassed = executor.get_webRequest().get_userContext().Title; 

     // i.e. -- build google table 
     // add rows received from rest (forEach is from MicrosoftAjax.js) 
     // list results array = executor.get_object().d.results 

     Array.forEach(executor.get_object().d.results, function (row) { 

     data.addRow(row.Title, row.Id, row.ModifiedBy.Name); 

     }, this); 
    } 
    } 
} 
+0

надеюсь, что это поможет ... – WhiteHat