Kendo ASP.NET основной сетки перетаскивания из нескольких строк проблема производительности - PullRequest
0 голосов
/ 05 октября 2018

У меня есть код ниже:

dropsGrid.table.kendoSortable({
        filter: ">tbody >tr",
        placeholder: $('<tr class="placeholder"><td colspan="11">Drop Here!</td></tr>'),
        hint: function (element) {
            var width = $('#Drops').width();
            var table = $('<table style="width: ' + width + 'px;" class="k-grid k-widget"></table>'),
                hint;

            table.append($('#Drops .k-state-selected').clone());
            table.css("opacity", 0.7);

            return table;
        },
        start: function (e) {
            if ($('#Drops .k-state-selected').length == 0) {
                e.preventDefault();
            } else {
                $('#Drops .k-state-selected').hide();
            }
        },
        end: function (e) {
            $('#Drops .k-state-selected').show();
        },
        change: function (e) {
            try {
                isDropInProgress = true;

                var items = this.element.find('.k-state-selected').not(e.item);
                for (var i = 0; i < items.length; i++) {
                    console.log(items[i]);
                    $(items[i]).insertBefore(e.item).show();
                }

                var selectedSequence = $(e.item[0]).find('.row-number').text();
                for (var i = 0; i < items.length; i++) {
                    var sequence = $(items[i]).find('.row-number').text();
                    if (Number(sequence) > Number(selectedSequence)) {
                        $(e.item).insertBefore(items[i]);
                        break;
                    }
                }

                var rows = $(dropsGrid.tbody[0]).find('tr');
                for (var i = 0; i < rows.length; i++) {
                    var uid = $(rows[i]).data('uid');
                    var drops = dropsGrid.dataSource.data();
                    var dataItem = null;
                    for (var j = 0; j < drops.length; j++) {
                        if (drops[j].uid == uid) {
                            dataItem = drops[j];
                            break;
                        }
                    }
                    if (dataItem != null) {
                        dropsGrid.dataSource.remove(dataItem);
                        dropsGrid.dataSource.insert(i, dataItem);
                    }
                }

            } finally {
                isDropInProgress = false;
                isDirty = true;
                onDataBound();
                refreshMap(dropsGrid.dataSource._data);
            }
        },
        cancel: function (e) {
            $('#Drops .k-state-selected').show();
        }
    }).data("kendoSortable");

С этим кодом пользователь может изменить порядок строк в сетке с помощью перетаскивания.Также "refreshMap (dropsGrid.dataSource._data);"обновляет булавки на карте Google, когда пользователь изменяет порядок строк.

Все работает, как и ожидалось, но если сетка содержит, скажем, 80 строк, и вы пытаетесь переместить 3 строки одновременнопроизводительность занимает значительное место.Т.е. для размещения строк требуется от 9 до 10 секунд.

Я провел некоторую отладку и обнаружил, что проблема в следующем фрагменте кода:

var rows = $(dropsGrid.tbody[0]).find('tr');
                for (var i = 0; i < rows.length; i++) {
                    var uid = $(rows[i]).data('uid');
                    var drops = dropsGrid.dataSource.data();
                    var dataItem = null;
                    for (var j = 0; j < drops.length; j++) {
                        if (drops[j].uid == uid) {
                            dataItem = drops[j];
                            break;
                        }
                    }
                    if (dataItem != null) {
                        dropsGrid.dataSource.remove(dataItem);
                        dropsGrid.dataSource.insert(i, dataItem);
                    }
                }

Последние пару дней я пытался заменить вложенные циклы for, но без полного успешного результата.

Я достиг того, что единственная выборка работала синхронно с картой, используя следующий код:

var skip = 0,
                oldIndex = e.oldIndex + skip,
                newIndex = e.newIndex + skip,
                //data = dropsGrid.dataSource.data(),
                dataItem = dropsGrid.dataSource.getByUid(e.item.data("uid"));

            console.log("------" + e.newIndex + " " + newIndex + " " + skip + " - " + e.oldIndex + " " + oldIndex + " " + skip);

            dropsGrid.dataSource.remove(dataItem);
            dropsGrid.dataSource.insert(newIndex, dataItem);

но я теряю функциональность множественного выбора.

Используя код ниже:

start: function (e) {
            if ($('.k-state-selected').length === 0) {
                e.preventDefault();
            } else {
                $('.k-state-selected').hide();
            }
        },
        end: function (e) {

            $('.k-state-selected').show();
        },
        change: function (e) {
            try {
                isDropInProgress = true;

                console.time("whole drop");

                var items = this.element.find('.k-state-selected').not(e.item);
                for (var i = 0; i < items.length; i++) {
                    console.log(items[i]);
                    $(items[i]).insertBefore(e.item).show();
                }

                var selectedSequence = $(e.item[0]).find('.row-number').text();
                for (var i = 0; i < items.length; i++) {
                    var sequence = $(items[i]).find('.row-number').text();
                    if (Number(sequence) > Number(selectedSequence)) {
                        $(e.item).insertBefore(items[i]);
                        break;
                    }
                }

                $('.k-state-selected').removeClass("state-selected");

                console.timeEnd("whole drop");
            } finally {
                isDropInProgress = false;
                isDirty = true;
                onDataBound();
                refreshMap(dropsGrid.dataSource._data);
            }
        },
        cancel: function (e) {
            $('.k-state-selected').show();
        }
    }).data("kendoSortable");

    testDrop.draggable.userEvents.bind("tap", function (e) {
        if (e.event.ctrlKey) {
            e.target.toggleClass("state-selected");
        } else {
            $('.k-state-selected').removeClass("state-selected");
            e.target.addClass("state-selected");
        }
    });

работает множественный и одиночный выбор, но контакты на карте больше не обновляются.

Еще одна проблема, связанная с описанным выше подходом, заключается в том, что при перемещении, скажем, двух строк из позиции 1 и 2 в строку 5, я получаю следующее поведение:

  • 2 строки, которые я переместил, выделены (ожидаемое поведение)

  • также выбраны строки, которые заменили позиции 1 и 2 (нежелательное поведение, поскольку это создает путаницу)

Вчера я придумал этот код:

dropsGrid.table.kendoSortable({
    filter: ">tbody >tr",
    placeholder: $('<tr class="placeholder"><td colspan="11">Drop Here!</td></tr>'),
    hint: function (element) {
        var width = $('#Drops').width();
        var table = $('<table style="width: ' + width + 'px;" class="k-grid k-widget"></table>'),
            hint;

        table.append($('#Drops .k-state-selected').clone());
        table.css("opacity", 0.7);

        return table;
    },
    start: function (e) {
        if ($('#Drops .k-state-selected').length == 0) {
            e.preventDefault();
        } else {
            $('#Drops .k-state-selected').hide();
        }
    },
    end: function (e) {
        $('#Drops .k-state-selected').show();
    },
    change: function (e) {
        try {
            isDropInProgress = true;

            console.time("whole drop");

            var grid = $('#' + dropsGridName).data("kendoGrid");    //$('#' + dropsGridName).data("kendoGrid");  //$('#Drops').data('kendoGrid');
            var rows = grid.select();
            var record = [];
            var uidSelectedRows;
            var selectedRowsIndex = [];
            rows.each(function() {
                record.push(grid.dataItem(this));
                uidSelectedRows = $(this).data('uid');
                var currentRowIndex = $(this).closest("tr").index();
                if (selectedRowsIndex.indexOf(currentRowIndex) === -1) {
                    selectedRowsIndex.push(currentRowIndex);
                }
                console.log("\n" + "This is the value of record: " + "\n" + record + "\n");
                console.log("\n" + "This is the value of uidSelectedRows: " + "\n" + uidSelectedRows + "\n");
                console.log("\n" + "This is the value of selectedRowsIndex: " + "\n" + currentRowIndex + "\n");
            });

            console.log("This is the value of selectedRowsIndex: " + "\n" + selectedRowsIndex);

                var uid = uidSelectedRows;
                var drops = dropsGrid.dataSource.data();
                var dataItem = null;
                console.log("first for loop");
                for (var j = 0; j < drops.length; j++) {
                    if (drops[j].uid === uid) {
                        dataItem = drops[j];
                        console.log("second for loop");
                        break;
                    }
                }
                if (dataItem != null) {
                    dropsGrid.dataSource.remove(dataItem);
                    dropsGrid.dataSource.insert(selectedRowsIndex, dataItem);
                    console.log("This the value of i:" + "\n" + i + "\n" +
                        "\n" + "This is the value of uid:" + "\n" + uid + "\n" + "This is the value of drops:" + "\n" + drops +
                        "\n" + "This is the value of j:" + "\n" + drops.length + "\n" + "This is the selectedRowsIndex" + "\n" + selectedRowsIndex);
                }

            console.timeEnd("whole drop");

        } finally {
            isDropInProgress = false;
            isDirty = true;
            onDataBound();
            refreshMap(dropsGrid.dataSource._data);
        }
    },
    cancel: function (e) {
        $('#Drops .k-state-selected').show();
    }
}).data("kendoSortable");

В приведенном выше примере перетаскивание множественного выбора не работает.

Поскольку я провел пару днейУже по этому вопросу мне было интересно, если вы можете, пожалуйста, помочь с примером или некоторыми рекомендациями для решения этой проблемы.

Я с нетерпением жду ответа от вас!

Спасибо

...