代码之家  ›  专栏  ›  技术社区  ›  Larry Lustig

替换行时无法使jQuery DataTable中的数据无效

  •  2
  • Larry Lustig  · 技术社区  · 8 年前

    我有一个小的jQuery数据表,它会定期逐个更新它的行。这是通过将该行替换为“更新”行、回调服务器、以html形式接收回一行,并将“更新”行替换为服务器提供的新html来实现的。这可以工作,用户可以看到更新的信息出现。

    但是,如果用户单击列标题,表中的行将返回到更新过程中几毫秒内的“更新”状态。

    下面是javascript,我在其中检索该行并尝试使其内容无效,以便DataTables将对该行的最新replacedWith()版本进行排序(并在排序后显示)。

    function getRow(svcName, rowId)
    {
        // Mark in progress
        $("#" + rowId).html("<td colspan='5'>" + svcName + "<i class='fa fa-refresh fa-spin fa-1x fa-fw'></i></td>").addClass('info');
    
        // Get the HTML
        $.ajax(
            {
                type: 'get',
                dataType: 'html',
                url: svcName,
                error: function (jqXHR, textStatus, errorText) {
                    $("#" + rowId).text("Error " + errorText + " (" + svcName + ")");
                    var row = $(".service-table").DataTable().row("#" + rowId);
                    row.invalidate('dom');
                },
                success: function (response, textStatus, jqXHR) {
                    // This response is visible in the table 
                    // UNTIL I sort the table, at which time it's the temporary 
                    // version of the row, above, which is restored 
                    // from the dataTable cache.
                    $("." + rowId).replaceWith(response);
                    var row = $(".service-table").DataTable().row("#" + rowId);
                    row.invalidate('dom');
                    //row.draw('row');
                }
            }
        );
    
    }
    

    如何强制dataTable知道我已替换了该行?

    更新:我已经按照RickL的回答更新了代码,但看到了类似的行为:

    function getRow(svcName, rowId)
    {
        // Mark in progress
        $("#" + rowId).html("<td colspan='5'>" + svcName + "<i class='fa fa-refresh fa-spin fa-1x fa-fw'></i></td>").addClass('info');
    
        // Get the HTML
        $.ajax(
            {
                type: 'get',
                dataType: 'html',
                url: svcName,
                success: function (response, textStatus, jqXHR) {
                    var table = $(".service-table:first").DataTable();
                    // get the index
                    var rowIndex = table.row("#" + rowId).index();
                    // get the jQuery representation of the row and replace
                    var $row = $(table.row(rowIndex).node());
                    $row.replaceWith(response);
                    table.row(rowIndex).invalidate(); //.draw(false);
                }
            }
        );
    
    }
    
    2 回复  |  直到 8 年前
        1
  •  1
  •   RickL    8 年前

    鉴于问题中的评论和参考,我将发布另一个答案(带评论):

    function getRow(svcName, rowId) {
        // Get row
        var selectedRow = $("#" + rowId);
        // Set row as in progress
        selectedRow.html("<td colspan='5'>" + svcName + "<i class='fa fa-refresh fa-spin fa-1x fa-fw'></i></td>").addClass('info');
        // Get replacement HTML
        $.ajax({
            type: 'get',
            dataType: 'html',
            url: svcName,
            success: function (response, textStatus, jqXHR) {
                // Get table
                var table = $("#grid").DataTable();
                // Get row index
                var rowIndex = table.row(selectedRow).index();
                // Change row html
                selectedRow.html($(response).html());
                // Iterate, update and reset each cell in the row
                // (this preserves sorting with new data)
                $.each(selectedRow.find("td"), function (i) {
                    table.cell(rowIndex, i).data($(this).html()).draw();
                });
            }
        });
    }
    

    通过测试,我发现使用这种方法,当单元格本身更新时,表列的排序是以这种方式保留的(这是一件好事)。

        2
  •  1
  •   RickL    8 年前

    我不完全清楚您在“更新”state时想做什么,您似乎有两种方法来选择有问题的行(class和id),但除此之外:

    // Get reference to table
    var table = $(".service-table:first").DataTable();
    // Get reference to row index (NOTE you have both
    // ("." + rowId) and ("#" + rowId) referenced ? This assumes id selector)
    var rowIndex = table.row("#" + rowId).index();
    // Get jQuery representation of row
    var $row = $(table.row(rowIndex).node());
    // Replace jQuery representation of row
    $row.replaceWith(response);
    // Invalidate DataTables representation of the row data
    // and redraw (with false parameter to keep table the same)
    table.row(rowIndex)
        .invalidate()
        .draw(false);
    

    我还没有对它进行测试(没有进一步的代码细节),但希望它的逻辑应该在那里。