jquery - 使用 JQuery 将文本添加到动态创建的 HTML 表
问题描述
我根据模型中的项目数动态创建一个表。
我希望能够<td>
在循环遍历每次迭代时为元素添加文本。
Razor 正在创建所有元素,但 JQuery 不会<td>
在GetTableData
函数中添加文本。
我已经测试过数据是从 AJAX 调用中返回的,我还测试过数据是真实的,所以这部分有效。
<td>
我的问题是,在进行 AJAX 调用后,如何在循环的每次迭代中将文本动态添加到元素中。
我的代码如下:
@{ 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 />
}
解决方案
在我回答这个问题之前,我不得不说你的代码中有很多错误。
- 您要注册
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
a 中分配给本地函数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
,<code>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。