Was ist der beste Weg, um die Sortierreihenfolge von Listenelementen mit der Drag & Drop-Benutzeroberfläche zu verwalten?


10

Ich habe eine Liste von Schülern, die ich dem Benutzer auf einer Webseite in Tabellenform anzeigen soll.
Die Elemente werden zusammen mit den SortOrder-Informationen in der Datenbank gespeichert.

Auf der Webseite kann der Benutzer die Listenreihenfolge ändern, indem er die Elemente in die gewünschte Sortierreihenfolge zieht und dort ablegt, ähnlich wie in diesem Beitrag .

Unten ist ein Screenshot meiner Testseite.
Geben Sie hier die Bildbeschreibung ein

Im obigen Beispiel sind jeder Zeile Informationen zur Sortierreihenfolge zugeordnet. Wenn ich John Doe (Schüler-ID 10) über der Zeile Schüler-ID 1 ablege, sollte die Listenreihenfolge jetzt wie folgt lauten: 2, 10, 1, 8, 11.

Wie kann die Sortierreihenfolge optimistisch (weniger ressourcenhungrig) gespeichert und aktualisiert werden?

Meine einzige Idee für den Moment ist, dass bei jeder Änderung der Sortierreihenfolge der Liste der SortOrder-Wert jedes Objekts aktualisiert werden sollte, was meiner Meinung nach sehr ressourcenhungrig ist.

Nur zu Ihrer Information: Ich könnte höchstens 25 Zeilen in meiner Tabelle haben.


1
Müssen Sie diese Sortierreihenfolge auf der Serverseite beibehalten, oder reicht es aus, sie nur auf der Clientseite zu haben?
Deterb

1
Ich sollte die Bestellung serverseitig speichern. Es spielt keine Rolle, ob die Bestellung bei jedem Drag-Drop oder durch ein für alle Mal Klicken auf eine Schaltfläche gespeichert wird.
Alexander

Antworten:


10

Ich habe an etwas gedacht, das Ihre Fragen reduzieren kann. Hier in meinem Beispiel habe ich einen neuen columnzum Sortieren mit dem Namen hinzugefügt pos. Zunächst wird Ihr Tisch also ohne Ziehen wie folgt aussehen:

Ausgangszustand

Betrachten wir nun, dass Sie das Zeichen Item 4zwischen Item 1& gezogen haben Item 2. Nun wird ein neuer posWert für Item 4sein (20 + 10) / 2, nämlich 15. Sie müssen also nur eine einzelne Zeile in der Datenbank aktualisieren. Und du wirst bekommen -

Nach dem Ziehen

Hier ist ein Flussdiagramm mit den Randfällen. iist der neue Array-Index Ihrer Zeile nach dem Ziehen -

Flussdiagramm

Dieses Flussdiagramm behandelt keine ArrayOutOfBoundPrüfungen. Für Randfälle benötigen Sie mehr als eine Abfrage.

Da Sie nur 25 Zeilen haben, können Sie einen sehr großen Wert (z. B. 10,000) für die Pos-Differenz verwenden (ich habe 10für dieses Beispiel genommen). Je größer der Wert ist, desto weniger kollidiert er.


Dies ist ein schöner Ansatz. Beachten Sie, dass Sie die gesamten (oder einen großen Teil) der Bestellinformationen neu berechnen müssen, wenn kein Platz zum Einfügen eines Artikels vorhanden ist. Es wäre selten genug, um es zu ertragen.
9000

@ 9000 Sie können Dezimalzahlen anstelle von Ganzzahlen verwenden, um das Problem zu vermeiden.
Rifat

Wenn Sie Item Amit Position 123 und Item Cmit Position 124 haben, gibt es keine einfache Möglichkeit, Item B zwischen ihnen zu setzen . Eine Lösung wäre die Verwendung von Bruchzahlen (z. B. Floats), die jedoch auch eine begrenzte Genauigkeit aufweisen. Manchmal ist es besser, eine Umnummerierung vorzunehmen, die Intervalle zu normalisieren und die Dinge einfach zu halten.
9000

Wenn Sie also i-- tun, subtrahieren Sie nur um 1. Gibt es nicht ein anderes Intervall, um das Sie subtrahieren könnten, um eventuelle Kollisionen zu verhindern?
Muttley91

@Rifat sogar Dezimalstellen haben eine begrenzte Genauigkeit, so dass sie auch kollidieren.
SCI

3

Persönlich würde ich ein JSON-Array für die Daten vom Back-End zurückgeben. Dann würde ich JavaScript (JQuery oder Knockout) verwenden, um die Daten anzuzeigen, zu sortieren und neu zu sortieren. Auf diese Weise hat die Sortierung keine Last auf dem Server.


0

Sie suchen nach einem ressourcenschonenden Weg, um damit umzugehen, aber auch eine benutzerfreundliche Perspektive ist ein Muss. Ich empfehle individuelle Anfragen nach jedem nachbestellten Artikel. Bei jedem Anruf können Sie überprüfen, ob er angenommen wurde oder fehlgeschlagen ist.

  • Fehlgeschlagene Antworten setzen die Ansicht zurück und zeigen dem Endbenutzer eine Nachricht an.
  • Akzeptierte Anfragen einfach ermöglicht die weitere Bearbeitung.

Alternativ ist die Verwendung eines JSON-Objekts (@ tom-squires) eine gute Idee, um den HTTP-Overhead und die serverseitige Verarbeitung zu reduzieren, erfordert jedoch letztendlich mehr Code, um Anforderungen auf der Server- und Clientseite zu verarbeiten. Wenn dies in Ordnung ist, ist die Übergabe des Objekts an den Server technisch am effizientesten. Es ermöglicht auch eine Verzögerung von einigen Sekunden, um mehrere Nachbestellungen vor einer einzelnen Anfrage zu ermöglichen, wenn Sie dies wünschen.

Beachten Sie, dass Sie, um einem Benutzer ein Feedback zu fehlgeschlagenen Anforderungen zu geben, ein Antwort-JSON-Objekt vom Server analysieren müssen, um herauszufinden, welches Element fehlgeschlagen ist, und die Benutzeroberfläche basierend darauf zurücksetzen müssen.


-1

So etwas im Drop-Event-Handler, wobei e das DnD-Ereignis ist.

        ....
        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;
        }
    ...
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.