【问题标题】:Unable to invalidate data in jQuery DataTable when replacing rows替换行时无法使 jQuery DataTable 中的数据无效
【发布时间】:2023-03-03 18:10:01
【问题描述】:

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

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

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

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);
            }
        }
    );

}

【问题讨论】:

    标签: jquery datatables


    【解决方案1】:

    由于问题中的 cmets 和引用,我将发布另一个答案(使用 cmets):

    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();
                });
            }
        });
    }
    

    对此进行测试,我发现使用这种方法,随着单元格本身的更新,表格列的排序会以这种方式保留(这是一件好事)。

    【讨论】:

    • 快到了!这可以在success 函数中使用selectedRow.html()(如您所写),但我的目标是改用selectedRow.replaceWith()(因为我需要返回的&lt;tr&gt; 元素上有上下文类)。当内部 HTML 被替换时,我的问题的核心似乎来自 DataTables “工作”,而不是当整个 &lt;tr&gt; 标记被替换时。我将尝试使用 .html() 并尝试将类从 $(response) 复制到现有行。
    • 是的,如果我在设置 html 后添加selectedRow.attr("class", $(response).attr("class"));,我会得到我想要的结果。感谢您花时间帮助我解决这个问题。
    • 不错的一个。很高兴它起作用了(并且有一个(有点涉及的)方法来做我猜是相当常见的 DataTables 功能,这非常有用)
    【解决方案2】:

    我并不完全清楚您要对“更新”状态进行什么操作,而且您似乎有两种选择相关行的方法(类和 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);
    

    我还没有测试过它(没有更多的代码细节),但希望逻辑应该可以解决它。

    【讨论】:

    • 谢谢,现在正在查看。该表是一组代表微服务的红色或绿色行。 “更新”状态旨在将一行变为蓝色(并显示一个微调器),同时查询后端的当前状态。
    • 知道了,谢谢。请注意,代码中的表格选择器选择的是 .service-table 类的第一个表格(可能是这种情况,但你可能有多个)
    • 不幸的是,无法正常工作。如果我完全按照您提供的代码保留代码,那么当调用getRow() 时,我根本看不到更新的行(只是“更新”行)。如果我删除 .draw(false) 并只删除 invalidate() 行,那么我 确实 会在表中看到更新的行,直到我对表进行排序,此时“更新”行被恢复(类似到原来的行为)。我将使用当前版本的代码更新问题。
    猜你喜欢
    • 1970-01-01
    • 2018-12-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-09
    • 2017-06-01
    • 1970-01-01
    • 2017-05-29
    相关资源
    最近更新 更多