Jaki jest najlepszy sposób zarządzania kolejnością sortowania elementów listy za pomocą interfejsu Drag & Drop?

10

Mam listę studentów, którą powinienem wyświetlić użytkownikowi na stronie internetowej w formacie tabelarycznym.
Elementy są przechowywane w DB wraz z informacjami SortOrder.

Na stronie internetowej użytkownik może zmienić kolejność na liście, przeciągając i upuszczając elementy do pożądanej kolejności sortowania, podobnie jak w tym poście .

Poniżej zrzut ekranu mojej strony testowej.
wprowadź opis zdjęcia tutaj

W powyższym przykładzie do każdego wiersza dołączone są informacje o kolejności sortowania. Kiedy upuszczam John Doe (Student Id 10) powyżej wiersza Student Id 1, kolejność na liście powinna teraz wynosić: 2, 10, 1, 8, 11.

Jaki jest optymistyczny (mniej wymagający zasobów) sposób przechowywania i aktualizowania informacji o sortowaniu?

Moim jedynym pomysłem na razie jest to, że przy każdej zmianie kolejności sortowania listy wartość SortOrder każdego obiektu powinna być aktualizowana, co moim zdaniem jest bardzo wymagające zasobów.

Tylko do twojej wiadomości: Mogę mieć maksymalnie 25 wierszy w mojej tabeli.

Alexander
źródło
1
Czy musisz mieć taki porządek sortowania po stronie serwera, czy wystarcza po prostu po stronie klienta?
deterb
1
Powinienem przechowywać zamówienie po stronie serwera. Nie ma znaczenia, czy kolejność jest zapisywana przy każdym przeciąganiu lub po kliknięciu przycisku raz na zawsze.
Alexander

Odpowiedzi:

10

Pomyślałem o czymś, co może ograniczyć twoje zapytania. Tutaj w moim przykładzie dodałem nowy columndo sortowania o nazwie pos. Tak więc początkowo bez przeciągania twój stół będzie wyglądał jak -

Stan początkowy

Rozważmy teraz, że przeciągnąłeś Item 4pomiędzy Item 1& Item 2. Teraz nowa poswartość dla Item 4będzie (20 + 10) / 2, czyli jest 15. Musisz więc zaktualizować tylko jeden wiersz w bazie danych. I dostaniesz -

Po przeciągnięciu

Oto schemat blokowy ze skrzynkami brzegowymi. ito nowy indeks tablicy wiersza po przeciągnięciu -

Schemat blokowy

Ten schemat blokowy nie obsługuje ArrayOutOfBoundczeków. A w przypadkach krawędzi potrzebujesz więcej niż jednego zapytania.

Ponieważ masz tylko 25 wierszy, możesz wziąć bardzo dużą wartość (np. 10,000) Dla różnicy pozycji (wziąłem 10dla tego przykładu). Im większa wartość, tym mniej się zderzy.

Rifat
źródło
To miłe podejście. Zauważ, że będziesz musiał ponownie obliczyć całość (lub dużą część) informacji o zamówieniu, jeśli nie ma miejsca, aby nie wstawić elementu. Byłoby to dość rzadkie wydarzenie, z którym należałoby się pogodzić.
9000
@ 9000 można użyć liczby dziesiętnej zamiast liczby całkowitej, aby uniknąć problemu.
Rifat
jeśli masz Item Apozycję 123 i Item Cpozycję 124, nie ma łatwego sposobu na umieszczenie Item B między nimi. Jednym rozwiązaniem byłoby użycie liczb ułamkowych (np. Liczby zmiennoprzecinkowe), ale mają one również ograniczoną precyzję. Czasami lepiej jest zrobić numerację, normalizować interwały i uprościć sprawę.
9000
Więc kiedy to zrobisz, odejmujesz tylko o 1. Czy nie ma innego przedziału, przez który można by odjąć, aby zapobiec ewentualnym kolizjom?
muttley91
@Rifat nawet miejsca dziesiętne mają ograniczoną precyzję, więc też się zderzą.
SCI,
3

Osobiście zwróciłbym tablicę JSON dla danych z zaplecza. Następnie użyłbym JavaScript (JQuery lub knockout) do wyświetlania i sortowania oraz ponownego sortowania danych. W ten sposób sortowanie nie obciąża serwera.

Tom Squires
źródło
0

Szukasz przyjaznego dla zasobów sposobu na poradzenie sobie z tym, ale przyjazna dla użytkownika perspektywa jest również koniecznością. Polecam indywidualne zamówienia po każdym zamówionym produkcie. Każde połączenie pozwala sprawdzić, czy zostało przyjęte czy nieudane.

  • Nieudane odpowiedzi resetują widok i wyświetlają komunikat dla użytkownika końcowego.
  • Proste zaakceptowane wnioski pozwalają na dalszą edycję.

Alternatywnie, użycie obiektu JSON (@ tom-squires) jest dobrym pomysłem, aby zmniejszyć obciążenie HTTP i przetwarzanie po stronie serwera, ale ostatecznie wymaga więcej kodu do obsługi żądań po stronie serwera i klienta. Jeśli to jest OK, przekazanie obiektu do serwera jest najbardziej technicznie wydajne. Pozwala to również na kilkuminutowe opóźnienie, aby umożliwić wielokrotne ponowne uporządkowanie przed pojedynczym żądaniem, jeśli tego chcesz.

Należy pamiętać, że aby przekazać użytkownikowi informację zwrotną na temat nieudanych żądań, trzeba przeanalizować obiekt JSON odpowiedzi z serwera, aby dowiedzieć się, który element się nie powiódł i na tej podstawie zresetować interfejs użytkownika.

David Garza
źródło
-1

Coś takiego w module obsługi zdarzenia drop, gdzie e jest zdarzeniem 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;
        }
    ...
Wejdź
źródło