Каков наилучший способ управления порядком сортировки элементов списка с помощью Drag & Drop UI?

10

У меня есть список студентов, который я должен отобразить пользователю на веб-странице в табличном формате.
Элементы хранятся в БД вместе с информацией SortOrder.

На веб-странице пользователь может изменить порядок списка, перетаскивая элементы в желаемый порядок сортировки, аналогично этому сообщению .

Ниже приведен скриншот моей тестовой страницы.
введите описание изображения здесь

В приведенном выше примере к каждой строке прикреплена информация о порядке сортировки. Когда я опускаю John Doe (Student Id 10) над строкой Student Id 1, список должен выглядеть следующим образом: 2, 10, 1, 8, 11.

Каков оптимистичный (менее ресурсоемкий) способ хранения и обновления информации о порядке сортировки?

Моя единственная идея на данный момент заключается в том, что при каждом изменении порядка сортировки списка значение SortOrder каждого объекта должно обновляться, что, на мой взгляд, очень ресурсоемко.

Только к вашему сведению: в моей таблице может быть не более 25 строк.

Александр
источник
1
Вам нужно, чтобы этот порядок сортировки сохранялся на стороне сервера, или его достаточно на стороне клиента?
Определить
1
Я должен хранить заказ на стороне сервера. Не имеет значения, хранится ли ордер при каждом перетаскивании или при нажатии кнопки раз и навсегда.
Александр

Ответы:

10

Я думаю о чем-то, что может уменьшить ваши запросы. Здесь, в моем примере, я добавил новый columnдля сортировки имени pos. Итак, изначально без каких-либо перетаскиваний ваш стол будет похож на -

Начальное состояние

Теперь давайте посмотрим, что вы перетянули Item 4между Item 1& Item 2. Теперь, новое posзначение Item 4будет (20 + 10) / 2, что 15. Таким образом, вам нужно будет обновить только одну строку в базе данных. И вы получите -

После перетаскивания

Вот блок-схема с крайними случаями. iновый индекс массива вашей строки после перетаскивания -

Блок-схема

Эта блок-схема не обрабатывает ArrayOutOfBoundпроверки. И для крайних случаев вам потребуется более одного запроса.

Так как у вас есть только 25 строк, вы можете принять очень большое значение (например 10,000) для разницы между позициями (я взял 10для этого примера). Чем больше значение, тем меньше оно будет сталкиваться.

Рифат
источник
Это хороший подход. Обратите внимание, что вам придется пересчитать всю (или большую часть) информацию о заказе, если нет места для вставки предмета. Это было бы достаточно редкое событие, чтобы смириться.
9000
@ 9000 вы можете использовать десятичное вместо целого числа, чтобы избежать проблемы.
Праздник
если у вас Item Aс позицией 123 и Item Cс позицией 124, Item B между ними нет простого способа . Одним из решений будет использование дробных чисел (например, чисел с плавающей точкой), но они также имеют ограниченную точность. Иногда вам лучше выполнять перенумерацию, нормализацию интервалов и упрощение.
9000
Поэтому, когда вы делаете i--, вы просто вычитаете на 1. Разве нет другого интервала, который вы могли бы вычесть, чтобы предотвратить возможные столкновения?
muttley91
@Rifat даже десятичные дроби имеют ограниченную точность, поэтому они тоже будут сталкиваться.
SCI
3

Лично я бы возвратил массив JSON для данных из серверной части. Затем я использовал бы JavaScript (JQuery или knockout) для отображения, сортировки и повторной сортировки данных. Таким образом, сортировка имеет нулевую нагрузку на сервер.

Том Сквайрс
источник
0

Вы ищете удобный для решения этой проблемы ресурс, но удобная точка зрения также необходима. Я рекомендую индивидуальные запросы после каждого заказа. Каждый звонок позволяет вам проверить, принят он или нет.

  • Неудачные ответы сбрасывают представление и отображают сообщение для конечного пользователя.
  • Принятые запросы просто позволяют продолжить редактирование.

В качестве альтернативы, использование объекта JSON (@ tom-squires) является хорошей идеей для сокращения накладных расходов HTTP и обработки на стороне сервера, но в конечном итоге требует больше кода для обработки запросов на стороне сервера и клиента. Если все в порядке, передача объекта на сервер наиболее технически эффективна. Он также допускает задержку в пару секунд, чтобы сделать возможным несколько повторных заказов перед одним запросом, если вы этого хотите.

Имейте в виду, что для предоставления пользователю обратной связи по неудавшимся запросам вам нужно будет проанализировать ответный объект JSON с сервера, чтобы выяснить, какой элемент не выполнен, и сбросить пользовательский интерфейс на его основе.

Дэвид Гарза
источник
-1

Примерно так в обработчике события drop, где e - событие DnD.

        ....
        if (e.Action == DragAction.Drop)
        {
            foreach(var item in Items)
            {
                if (e.NewIndex == e.OldIndex) // Dropped in same place
                    return;
                if(e.OldIndex > e.NewIndex) // Moved Up
                {
                    if (item.SortOrder >= e.NewIndex && item.SortOrder < e.OldIndex)
                    {
                        item.SortOrder ++;
                    }
                }
                else // Moved Down
                {
                    if (item.SortOrder> e.OldIndex && item.SortOrder < e.NewIndex) 
                    {
                        item.SortOrder --;
                    }
                }   
            }
            ((Student)e.ItemData).SortOrder = e.NewIndex;
        }
    ...
Заходи
источник