Улучшение jQuery производительности таблицы данных master-detail - PullRequest
0 голосов
/ 18 февраля 2020

Я создал таблицу данных master-detail, используя таблицу данных jQuery. Он работает нормально, но его производительность далека от желаемой. Я полагаю, это потому, что каждый раз, когда я раскрываю строку, чтобы показать ее детали, она перерисовывает всю таблицу. Мне нужно показать все строки в master, а не только первые X записи. Мне было интересно, может ли какой-нибудь гуру здесь предложить какое-то улучшение кода.

Это то, что я сейчас использую:

Стили для открытия / закрытия изображений:

<style>
    td.details-control {
        background: url('../assets/images/details_open.png') no-repeat center center;
        cursor: pointer;
    }

    tr.shown td.details-control {
        background: url('../assets/images/details_close.png') no-repeat center center;
    }
</style>

Основные / Подробные таблицы и функции:

<table id="MasterTable" class="table table-striped table-bordered table-hover display responsive status" style="width:98%;">
    <thead>
        <tr class="info">
            <th></th>
            <th>Time</th>
            <th>...</th>
        </tr>
    </thead>
    <tbody>
    </tbody>
    <tfoot>
    </tfoot>
</table>

<script type="text/javascript">
    var iTableCounter = 1;
    var oInnerTable = new Object;
    var MasterTable = new Object;

    function addMasterDataTableListener() {
        // Add event listener for opening and closing details
        $('#MasterTable tbody').on('click', 'td.details-control', function () {
            var tr = $(this).closest('tr');
            var row = tblMasterItems.row(tr);
            var edl = row.data().EDL;
            var bin = row.data().BIN;

            if (row.child.isShown()) {
                // This row is already open - close it
                row.child.hide();
                tr.removeClass('shown');
            }
            else {
                // Add the html table shell of the datatable.
                row.child(formatMasterTableDetailRow(iTableCounter)).show();

                //show the datatable row.
                tr.addClass('shown');

                // datatable stuff
                oInnerTable =  buildDetailsDataTable(row.data(), iTableCounter);
                populateItemsTable(oInnerTable, edl, bin);
                iTableCounter = iTableCounter + 1;
            }
        });
    }

    function populateMasterItemsTable() {
        var startDateTime = $('#tbStartDateTime').val();
        var endDateTime = $('#tbEndDateTime').val();
        $.ajax({
            type: "POST",
            dataType: "json",
            contentType: "application/json; charset=utf-8",
            url: "../Services/Some.asmx/GetInfo",
            cache: false,
            data: JSON.stringify({ StartDate: startDateTime, EndDate: endDateTime }),

            success: function (result, textStatus, XMLHttpRequest) {
                tblMasterItems.clear().draw();

                if (!result || result.d === "") {
                }
                else {
                    jResult = JSON.parse(result.d);
                    tblMasterItems.rows.add(jResult).draw();
                }
            },
            error: function (jqXHR, textStatus, errorThrown) {
            }
        });
    }

    tblMasterItems = $("#MasterTable").DataTable({
        jQueryUI: true,
        data: [],
        dom: 'frtip',
        scrollY: 400,
        scrollCollapse: true,
        stateSave: true,
        stateDuration: 60 * 10,
        //"lengthMenu": [[10, 25, 50, -1], [10, 25, 50, "All"]],
        order: [[0, "desc"]],
        autoWidth: false,
        paging: false,
        "oLanguage": {
            "sEmptyTable": "No inforamtion available."
        },        
        "columns": [
            {
                "className": 'details-control',
                "orderable": false,
                "data": null,
                "defaultContent": ''
            }, {
                "data": "UPDATETIME"
            },
            }, {
                "data": "..."
            } 
        ],
        "columnDefs": [
            ...
        ],
        "pageLength": -1,
        processing: true,
        deferRender: true,
        "stateSave": function (oSettings, oData) {
            localStorage.setItem('MasterTable', JSON.stringify(oData));
        },
        "stateLoad": function (oSettings) {
            return JSON.parse(localStorage.getItem('MasterTable'));
        },
        "initComplete": function (settings, json) {
            this.api().columns.adjust().draw();
        }
    });

    function buildDetailsDataTable(parentObjData, tableCounter) {
        oInnerTable = $("#itemsDataTable_" + tableCounter).DataTable({
            jQueryUI: true,
            data: [],
            dom: 'tip',
            stateSave: true,
            stateDuration: 60 * 10,
            info: false,
            showEntries: false,
            order: [[7, "desc"]],
            autoWidth: false,
            paging: false,
            language: {
                emptyTable: "There are no items for selected row."
            },
            "columns": [
                {
                    "orderable": false,
                    "data": null,
                    "defaultContent": ''
                }, {
                    "data": "ITEMID1"
                }, {
                }, {
                    "data": "..."
                }
            ],
            "columnDefs": [
                ...
            ],
            "pageLength": -1,
            processing: true,
            deferRender: true
        });
        return oInnerTable;
    }

    function populateItemsTable(oInnerTable, edl, bin) {
        $.ajax({
            type: "POST",
            dataType: "json",
            contentType: "application/json; charset=utf-8",
            url: "../services/Some.asmx/GetDetails",
            cache: false,
            data: JSON.stringify({ Bin: bin, EDL: edl }),
        }).done(function (result) {
            oInnerTable.clear().draw();
            if (!result || result.d === "") {
            }
            else {
                jResult = JSON.parse(result.d);
                oInnerTable.rows.add(jResult).draw();
                oInnerTable.draw(false);
            }
        }).fail(function (jqXHR, textStatus, errorThrown) {
        });
    }

    function formatMasterTableDetailRow(table_id) {
        return  '<div class="table-responsive">' +
                '    <table id="itemsDataTable_' + table_id + '" class="table table-striped table-bordered pull-left">' +
                '        <thead>' +
                '            <tr>' +
                '                <th></th>' +
                '                <th>Item ID 1</th>' +
                '                <th>...</th>' +
                '            </tr>' +
                '        </thead>' +
                '        <tbody></tbody>' +
                '    </table>' +
                '</div>';
    }

</script>
...