使用JQuery将文本添加到动态创建的HTML表中

问题描述 投票:0回答:1

我根据模型中的项目数动态创建表。

我希望能够在循环遍历每次迭代时添加<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 &lt 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 &gt 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 />
    }
jquery asp.net-core razor html-table dynamically-generated
1个回答
0
投票

在回答这个问题之前,我不得不说你的代码中存在很多错误。

  1. 您正在多次注册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中的函数locals,这将使最后定义的函数有效。

  1. 你以错误的方式调用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 &lt Min</th>
            <td width="25%">${td4}</td>
        </tr>
        <tr>
            <th width="25%">Average</th>                
            <td width="25%">${td5}</td>
            <th width="25%">Time: Value &gt 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>

(名称td1td2等不好,您可以将它改为loggerIdreading,如你所愿)

让我们定义一个简单的函数来渲染这个模板:

<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。

© www.soinside.com 2019 - 2024. All rights reserved.