我根据模型中的项目数动态创建一个表。
我希望能够在循环遍历每次迭代时添加<td>
元素的文本。
Razor正在创建所有元素,但JQuery不会在<td>
函数中添加GetTableData
的文本。
我已经测试了数据是从AJAX调用返回的,我还测试了数据是真实的,因此这部分工作。
我的问题是,在进行AJAX调用之后,如何在循环的每次迭代中将文本动态添加到<td>
元素中。
我的代码如下:
@{ Char celsius = (Char)176;
int i = 0;
}
@foreach (var item in Model.ChartTableData)
{
i++;
string chartDiv = "chart" + i;
string td1;
string td2;
string td3;
string td4;
string td5;
string td6;
string td7;
string td8;
string td9;
string td10;
string td11;
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;
td11 = "td11" + i;
<script>
google.charts.load('current', { 'packages': ['corechart'] });
google.charts.setOnLoadCallback(drawLineChart);
function drawLineChart() {
var serial = @item.SerialNumber;
var uid = '@guid';
var from = '@item.FirstReading';
var to = '@item.LastReading';
console.log('Chart: ' + serial + ' ' + uid + ' ' + from + ' ' + to);
data = new google.visualization.DataTable();
chart = new google.visualization.ComboChart(document.getElementById('chart' + @i));
data.addColumn('date', 'Date');
data.addColumn('number', 'Data');
var parsedData = "";
$.ajax({
url: '/ReportGenerator/GetJsonChartData',
datatype: 'json',
type: 'get',
async: false,
data: { serial: serial, uid: uid, from: from, to: to },
contentType: 'application/json; charset=utf-8',
success: function (d) {
GetTableData(serial, uid, from, to);
parsedData = $.parseJSON(d);
$.each(parsedData, function (index, item) {
data.addRow([new Date(item.ReadingDate), Number(item.ReadingValue)]);
});
},
error: function () {
alert("Error loading chart");
}
});
var options = lineChartOptions(serial);
chart.draw(data, options);
};
function lineChartOptions(serial) {
var options = {
title: 'Logger data: ' + serial,
legend: {
position: 'none'
},
height: $(window).height() * 0.5,
hAxis: {
title: 'Date',
format: 'dd-MMM-yy',
titletextStyle: {
color: '#333'
}
}
}
return options;
}
function GetTableData(serial, uid, from, to) {
console.log('Table: '+serial + ' ' + uid + ' ' + from + ' ' + to);
var celsius = String.fromCharCode(176) + 'C';
//var parsedData = "";
$.ajax({
url: '/ReportGenerator/GetJsonTableData',
datatype: 'json',
type: 'get',
async: false,
data: { serial: serial, uid: uid, from: from, to: to },
contentType: 'application/json; charset=utf-8',
success: function (d) {
parsedData = $.parseJSON(d);
},
error: function () {
alert("Error loading chart");
}
});
console.log(parsedData[0].Average);
var avg = parsedData[0].Average;
var firstReading = parsedData[0].FirstReading;
var lastReading = parsedData[0].LastReading;
var loggerId = parsedData[0].SerialNumber;
var stdDev = parsedData[0].StdDev;
var mkt = parsedData[0].Mkt;
var maxTemp = parsedData[0].MaxTemp;
var minTemp = parsedData[0].MinTemp;
var upperT = parsedData[0].UpperThreshold;
var lowerT = parsedData[0].LowerThreshold;
var timeAboveAlert = parsedData[0].TimeAboveEqualUpperAlert;
var timeBelowAlert = parsedData[0].TimeBelowEqualLowerAlert;
var notInAlert = parsedData[0].TimeNotInAlert;
$('#@td1').text(loggerId);
$('#@td2').text(firstReading + " to " + lastReading);
$('#@td3').text(avg + celsius);
$('#@td4').text(stdDev + celsius);
$('#@td5').text(minTemp + celsius + '/' + maxTemp + celsius);
$('#@td6').text(timeAboveAlert);
$('#@td7').text(timeBelowAlert);
$('#@td8').text(notInAlert);
$('#@td9').text(mkt + celsius);
$('#@td10').text(lowerT + celsius + '/' + upperT + celsius);
var max = Math.ceil((maxTemp + 1) / 10) * 10;
var min = Math.floor((minTemp + 1) / 10) * 10
return [min, max, lowerT, upperT];
}
</script>
<div id="@chartDiv" style="display:block;margin-left:auto;margin-right:auto;width:100%;"></div>
<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%" id="@td1"></td>
<th width="25%">Min/Max Thresholds</th>
<td width="25%" id="@td2"></td>
</tr>
<tr>
<th width="25%">Date Range</th>
<td width="25%" id="@td4"></td>
<th width="25%">Time: Value < Min</th>
<td width="25%" id="@td5"></td>
</tr>
<tr>
<th width="25%">Average</th>
<td width="25%" id="@td6"></td>
<th width="25%">Time: Value > Max</th>
<td width="25%" id="@td7"></td>
</tr>
<tr>
<th width="25%">Lowest/Highest Value</th>
<td width="25%" id="@td8"></td>
<th width="25%">Time: Within Min/Max </th>
<td width="25%" id="@td9"></td>
</tr>
<tr>
<th width="25%">Std. Deviation</th>
<td width="25%" id="@td10"></td>
<th width="25%">Time: Out of Min/Max</th>
<td width="25%"></td>
</tr>
<tr>
<th width="25%">MKT </th>
<td width="25%" id="MKT"></td>
<th width="25%"></th>
<td width="25%"></td>
</tr>
</table>
<br />
}
答案 0 :(得分:0)
在回答这个问题之前,我必须说您的代码中有很多错误。
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
,这将使最后定义的函数仅有效。
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
获取dataList或在服务器端呈现它。您所需要做的就是循环该数组,使用不同的模型将模板呈现为字符串,最后更新DOM。