Прежде чем ответить на этот вопрос, я должен сказать, что в вашем коде довольно много ошибок.
- Вы регистрируете
OnLoadCallback
несколько раз и определяете одни и те же функции несколько раз:
@foreach (var item in Model.ChartTableData)
{
<script>
google.charts.load('current', { 'packages': ['corechart'] });
google.charts.setOnLoadCallback(drawLineChart);
function drawLineChart() {
// .... assign @guid, @item ... to locals
}
function lineChartOptions(serial) {
// ...
}
function GetTableData(serial, uid, from, to) {
// ...
}
</script>
...
}
Что еще хуже, вы присваиваете @item
локальным функциям в пределах foreach loop
, что сделает только последнюю определенную функцию действительной.
Вы вызываете ajax неправильно.Они асинхронные:
function drawLineChart() {
$.ajax({
// ...
success: function (d) { // async success
GetTableData(serial, uid, from, to); // async ajax
parsedData = $.parseJSON(d);
$.each(parsedData, function (index, item) {
data.addRow([new Date(item.ReadingDate), Number(item.ReadingValue)]);
});
});
var options = lineChartOptions(serial);
chart.draw(data, options);
}
Обратите внимание, что $.ajax()
- это async
.В результате, chart.draw(data,options)
запускается перед GetTableData()
.
Что касается вашего вопроса:
Мой вопрос: как я могу динамически добавить текст вэлемент на каждой итерации цикла после вызова AJAX.
Поскольку вы хотите модифицировать DOM несколько раз, поиск элементов неэффективен по $("#td1")
, $("#td2")
,$("#td3")
, ... и измените их текстовые времена и времена.
Мы могли бы определить общий шаблон:
<script type="text/template" id="table-template" >
<table class="table table-sm table-bordered" style="width:100%; font-size:small;">
<tr class="text-center">
<th colspan="4" style="font-size:small; background-color:black; color:white;"><h6>Performance Data and Information</h6></th>
</tr>
<tr>
<th width="25%">Logger ID</th>
<td width="25%">${td1}</td>
<th width="25%">Min/Max Thresholds</th>
<td width="25%">${td2}</td>
</tr>
<tr>
<th width="25%">Date Range</th>
<td width="25%">${td3}</td>
<th width="25%">Time: Value < Min</th>
<td width="25%">${td4}</td>
</tr>
<tr>
<th width="25%">Average</th>
<td width="25%">${td5}</td>
<th width="25%">Time: Value > Max</th>
<td width="25%">${td6}</td>
</tr>
<tr>
<th width="25%">Lowest/Highest Value</th>
<td width="25%">${td7}</td>
<th width="25%">Time: Within Min/Max </th>
<td width="25%">${td8}</td>
</tr>
<tr>
<th width="25%">Std. Deviation</th>
<td width="25%">${td8}</td>
<th width="25%">Time: Out of Min/Max</th>
<td width="25%">${td9}</td>
</tr>
<tr>
<th width="25%">MKT </th>
<td width="25%"id="MKT">${td10}</td>
<th width="25%"></th>
<td width="25%"></td>
</tr>
</table>
</script>
(имена td1
, td2
и т. Д.не хорошо, вы можете изменить его на loggerId
, reading
, как вам нравится)
Давайте определим простую функцию для визуализации этого шаблона:
<script>
function renderer(templateStr){
var itemTpl = templateStr.split(/\$\{(.+?)\}/g);
return function render(model){
return itemTpl.map((token,idx)=> idx%2 ===0 ? token : model[token]).join('');
};
}
</script>
И теперь мы можем сделатьшаблон несколько раз, как показано ниже:
<script>
// model list
var dataList= [ /*...*/ ]; // by ajax , or render it on server side
// get the template string
var tmpl= document.getElementById("table-template").innerHTML;
// generate a render function to render the above template
var render = renderer(tmpl);
for(var i =0; i< dataList.length;i++){
// construct a model via `dataList[i]`
// e.g:
var model = {td1:"td1-"+i,td2:"td2:"+i,td3:"td3:"+i,td4:"td4:"+i,td5:"td5:"+i,td6:"td6:"+i,td7:"td7:"+i,td8:"td8:"+i,td9:"td9:"+i,td10:"td10:"+i};
var table = render(model); // the template string
var wrapper=document.createElement("div"); // create DOM element
wrapper.innerHTML= table;
document.body.appendChild(wrapper);
}
</script>
Здесь вы можете получить список данных с помощью ajax
или отобразить его на стороне сервера.Все, что вам нужно, это зациклить этот массив, отобразить шаблон в виде строки с другой моделью и, наконец, обновить DOM.