Funktionen zur Implementierung dynamischer Listen in Benutzeroberflächen

Bild

Die Oberfläche jeder modernen Anwendung in der einen oder anderen Form enthält Listen von Objekten. Wenn der Benutzer mit ihnen arbeitet, benötigt er häufig die gleichen Aktionen wie Sortieren, Filtern, Exportieren usw. Die Implementierung dieser Operationen wird oft dadurch erschwert, dass Listen "dynamisch" sein können. In diesem Fall werden die Daten bei Bedarf nicht nur vom Server zum Client, sondern auch vom Datenbankserver zum Anwendungsserver gelesen.

In der offenen und kostenlosen lsFusion- Plattform sind alle Listen standardmäßig dynamisch und werden in wenigen Codezeilen zu jeder Form hinzugefügt. In diesem Artikel werde ich Ihnen einige technische Details zu ihrer Implementierung sowie Funktionen in der Benutzeroberfläche erläutern, die dem Benutzer automatisch zur Verfügung gestellt werden, wenn er mit einer Liste in einem beliebigen Formular arbeitet.

Schöpfung


Listen im Formular in lsFusion werden durch die Anweisung OBJECTS hinzugefügt:
OBJECTS i = Item
Dem Formular wird eine Tabelle hinzugefügt, in der alle Objekte der Item- Klasse in den Zeilen enthalten sind. Sie können einer einzelnen Liste mehrere Objekte hinzufügen. Zum Beispiel
OBJECTS (i = Item, s = Stock)
In diesem Fall werden in der Tabelle alle möglichen Objektpaare der Klassen Item und Stock angezeigt.

Spalten werden der Liste mit der PROPERTIES- Anweisung hinzugefügt :
PROPERTIES name(i), name(s), quantityOnHand(i, s)
In der Tabelle können als einfache Details des Objekts auch beliebige Ausdrücke mit Gruppierungen, Partitionierungen, Rekursionen usw. hinzugefügt werden.

Standardmäßig werden in der Liste alle Objekte in der Datenbank angezeigt. Um sie einzuschränken , können Sie die FILTERS-Anweisung verwenden :
FILTERS quantityOnHand(i, s) > 0
In der Filterbedingung können Sie einen beliebigen Ausdruck verwenden, der von beliebigen Objekten im Formular abhängig ist.

Navigation


Wenn der Benutzer das Formular öffnet, ermittelt die Plattform abhängig von der Größe der Tabelle automatisch die Anzahl der sichtbaren Datensätze. Zur Vereinfachung der Darstellung wird davon ausgegangen, dass es 50 solcher Datensätze gibt. Zu jedem Zeitpunkt speichert die Plattform 150 Datensätze auf dem Client und auf dem Server. In diesem Fall sollte sich das aktuell aktive Objekt in der Mitte dieses „Fensters“ befinden: vom 50. bis zum 99. Datensatz. Es können weniger Einträge vorhanden sein, wenn sich das aktuelle Objekt entweder ganz am Anfang oder am Ende der Liste befindet.

Wenn Sie beim Öffnen des Formulars einen bestimmten Datensatz aktivieren müssen, werden zwei Anforderungen an den Datenbankserver gesendet, die jeweils 75 Datensätze auf jeder Seite des gewünschten Datensatzes lesen. Dann wird eine allgemeine Liste aus ihren Ergebnissen erstellt. Wenn Sie die Liste von Anfang bis Ende initialisieren müssen, werden 100 Datensätze angefordert und der erste oder letzte empfangene Datensatz wird aktiviert. Dasselbe passiert, wenn der Benutzer STRG + STARTSEITE oder STRG + ENDE in der Liste drückt, um an den Anfang oder das Ende der Liste zu gelangen.

Sobald der Benutzer eine aktive Aufzeichnung außerhalb der Mitte des aktuellen Fensters vornimmt (vor dem 50. oder nach dem 99.), liest die Plattform zusätzliche Datensätze, sodass sich der aktuelle Datensatz genau in der "Mitte" des neuen Fensters befindet.

Die Besonderheit einer solchen dynamischen Listenimplementierung besteht darin, dass sich das aktuelle Objekt nicht außerhalb der Mitte des Fensters befinden darf. Wenn Sie durch die Liste scrollen, wird das aktuelle Objekt automatisch in den sichtbaren Bereich verschoben.
Bild


Das Lesen von Daten in einer Liste erfolgt immer in zwei Abfragen. Die erste Abfrage liest nur die Schlüssel der erforderlichen Datensätze in der temporären Tabelle. Die zweite Abfrage liest die Werte aller Spalten für die bereits gelesenen Schlüssel. Dies geschieht aus dem Grund, dass die Spalten beliebige Ausdrücke enthalten können, die zu Unterabfragen oder anderen komplexen SQL-Konstrukten kompiliert werden können. In diesem Fall werden diese Schlüssel von der Plattform selbst in Unterabfragen verschoben, sodass die Berechnung der Werte dieser Spalten nicht in der gesamten Datenbank, sondern nur nach den erforderlichen Schlüsseln erfolgt. Dies verursacht einen geringfügigen Mehraufwand, da zwei Abfragen anstelle von einer durchgeführt werden, schützt jedoch vor dem versehentlichen "Einstieg" in einen ineffizienten Datenbankserverplan.

Filtern


Einträge in der Liste des Formulars können anhand der folgenden Optionen gefiltert werden:

  • Angabe im fortlaufenden Auswahlcode mit der Anweisung FILTERS:
    FILTERS <>
    Der Ausdruck kann von anderen aktuell ausgewählten Objekten im Formular abhängen. Befindet sich im Formular beispielsweise eine Tabelle oder ein Baum mit einem Warenlager, können Sie im Ausdruck für die Warenliste auf das aktuelle Warenlager verweisen, um nur die Waren zu filtern, die sich auf dem Kontostand befinden.
  • Angabe im Auswahlcode, der vom Benutzer bei Bedarf mit der Anweisung FILTERGROUP angewendet werden kann:
    FILTERGROUP myFilters
    FILTER 'Filter 1' <expression> 'F5' DEFAULT
    FILTER 'Filter 2' <expression> 'F6'

    Dem Formular wird eine Dropdown-Liste hinzugefügt (oder ein Kontrollkästchen, wenn die Gruppe einen Filter enthält), mit dem der Benutzer einen der anzuwendenden Filter auswählen kann.
    Bild
  • Manuelles benutzerdefiniertes Filtern durch den Benutzer in der Benutzeroberfläche:
    Bild
    Wenn die Spalte in der Liste nicht bearbeitet werden kann, wird bei der Eingabe von Zeichen automatisch der Filter für diese Spalte aktiviert, der durch einmaliges Drücken der ESC-Taste zurückgesetzt werden kann.

Die Plattform selbst überwacht Änderungen aller Bedingungen, die sich auf den aktuellen Filter auswirken können (Änderung abhängiger Objekte, Benutzeraktionen usw.). Wenn solche Änderungen erkannt werden, wird die Liste automatisch aktualisiert, ohne dass das aktuell ausgewählte Objekt geändert wird. Dazu werden zwei Anfragen gestellt, 75 Einträge in jede Richtung von der aktuellen, sowie während der Initialisierung des Formulars.

Sortieren


Standardmäßig werden die Einträge in den Listen in aufsteigender Reihenfolge der internen Kennungen der Objekte sortiert. Diese Bezeichner werden beim Erstellen von Objekten automatisch in aufsteigender Reihenfolge generiert (gleichzeitig sind sie in allen Klassen global eindeutig), und Indizes bauen immer darauf auf.

Die Sortierung in der Liste kann wie folgt geändert werden:

  • Indem Sie im Code die Spalten angeben, nach denen über die ORDER- Anweisung sortiert wird:
    ORDER column1(o) DESC , column2(o)
  • Doppelklicken Sie auf die Spaltenüberschrift des Benutzers (halten Sie die STRG-Taste gedrückt, um eine verschachtelte Sortierung hinzuzufügen).
    Bild

Abhängig von der aktuellen Sortierung werden beim Lesen der Datensatzschlüssel die entsprechenden Spaltenausdrücke zum ORDER BY-Block der Anforderung hinzugefügt. Gleichzeitig wird der Sortierung immer die eindeutige Kennung des Objekts (der Objekte) hinzugefügt, um sicherzustellen, dass die Schlüssel aller Datensätze eindeutig sind.

Ein Ausdruck der Form: column1> value1 OR (column1 = value1 AND column2> value2) OR (column1 = value1 AND column2 = value2 AND key> value) wird der WHERE-Klausel der Anforderung hinzugefügt. Außerdem wird beim Lesen von Schlüsseln der LIMIT-Befehl mit der erforderlichen Anzahl lesbarer Datensätze zur Anforderung hinzugefügt. Beim Lesen von Datensätzen "up" werden die Reihenfolge in ORDER BY und der Ausdruck in WHERE entsprechend "gespiegelt", um die Datensätze in die entgegengesetzte Richtung zu lesen.

Es sollte beachtet werden, dass die Komplexität der Ausführung dieser Abfragen relativ gering ist, wenn ein geeigneter Index vorhanden ist (da der Index die Laufleistung ab dem aktuellen Schlüssel nur für eine bestimmte Anzahl von Datensätzen nach oben oder unten darstellt). Um die Arbeit mit der dynamischen Liste beim Sortieren nach Spalten column1, column2 zu beschleunigen, wird empfohlen, den folgenden Index zu erstellen:
INDEX column1(Object o), column2(o), o;
Wenn die Sortierung auf der berechneten Spalte basiert, kann sie dauerhaft gespeichert werden, wie in diesem Artikel beschrieben , und anschließend kann ein Index darauf erstellt werden.

Ein Merkmal einer solchen Implementierung ist das Fehlen einer "ehrlichen" Bildlaufleiste. Beim Lesen von Datensätzen wird nur die erforderliche Anzahl von ihnen gelesen. Eine Anforderung, die Gesamtzahl der Zeilen in der Liste über COUNT (*) mit dem gewünschten Filter abzurufen, kann zu einer vollständigen Ausführung der Tabelle oder des Index führen, was sich negativ auf die Leistung auswirkt. Das gleiche Problem tritt auf, wenn Datensätze durch das OFFSET-Konstrukt gelesen werden. Darüber hinaus sollte beachtet werden, dass beim Navigieren in einer Liste die Anzahl der darin enthaltenen Einträge von anderen Benutzern geändert werden kann, indem neue Änderungen vorgenommen werden.

Bearbeiten


Überraschenderweise konnten sie auf einigen sogar kommerziellen Plattformen die Möglichkeit zum Bearbeiten in dynamischen Listen nicht realisieren. Die Hauptschwierigkeit bei der Implementierung dieses Mechanismus besteht darin, dass nur das sichtbare Fenster auf dem Server und dem Client gespeichert wird und Änderungen innerhalb der gesamten Liste vorgenommen werden können.

In lsFusion gibt es keinen speziellen Mechanismus, der die Listenbearbeitung direkt implementiert. Diese Funktionalität wird als Teil des allgemeinen Sitzungsmechanismus implementiert.

Alle in der aktuellen Änderungssitzung vorgenommenen Änderungen werden in temporären Tabellen gespeichert. Wenn der Benutzer etwas im Formular bearbeitet (einschließlich des Werts in einem der Einträge), werden die neuen Werte mit den entsprechenden Schlüsseln in temporäre Tabellen geschrieben. Wenn dann die zweite Abfrage (nach Erhalt der Schlüssel) die Werte der Spalten liest, wird der Abfrage einfach der JOIN mit den entsprechenden temporären Tabellen mit Änderungen hinzugefügt.

Beim Speichern der Änderungssitzung wird eine Abfrage ausgeführt, die in einer Transaktion alle Werte aus temporären Tabellen in die Datenbank schreibt.

Gruppenanpassung


Häufig muss der Benutzer den Spaltenwert für alle ausgewählten Objekte in der Liste gleichzeitig ändern. Zu diesem Zweck befindet sich in der Symbolleiste jeder Liste eine spezielle Schaltfläche (mit der Tastenkombination F12). Durch Drücken von wird der normale Zellenbearbeitungsmodus aktiviert, die Änderungen werden jedoch nicht auf den aktuellen Datensatz, sondern auf alle ausgewählten angewendet.

Mit diesem Mechanismus können Sie schnell eine große Anzahl von Objekten nach festgelegten Kriterien bearbeiten:
Bild


Wie bei der normalen Bearbeitung werden Änderungen nicht sofort in der Datenbank gespeichert, sondern in temporären Tabellen aufgezeichnet. Dann muss der Benutzer auf die Schaltfläche Speichern klicken, um sie in die Datenbank zu schreiben. Der Nachteil dieses Ansatzes kann sein, dass der Benutzer die zusätzlichen Daten versehentlich ändert. Aber hier gilt, wie gesagt, das Prinzip: „Mit großer Kraft geht große Verantwortung einher“.

Listenübersicht


In jeder Liste hat der Benutzer die Möglichkeit, die Anzahl der Datensätze oder den Betrag anhand einer bestimmten Spalte in der aktuellen Auswahl herauszufinden. Dazu muss der Benutzer auf die entsprechenden Schaltflächen in der Symbolleiste einer bestimmten Liste klicken:
Bild


Um diese Daten zu erhalten, wird automatisch eine Anfrage mit dem Ausdruck COUNT (*) oder SUM generiert, in der der aktuelle Auswahlausdruck hinzugefügt wird. Mit dieser Funktion können Sie schnell Summen aus Listen abrufen, ohne Berichte erstellen zu müssen.

In der Desktop-Version des Clients ist es auch möglich, die Summe der ausgewählten Zellen analog zu Excel zu berechnen:
Bild


Kopieren / Einfügen


In der Desktop-Version hat der Benutzer die Möglichkeit, bestimmte Zellen zu markieren, STRG + C zu drücken und die Werte daraus in die Zwischenablage einzufügen:
Bild


Auf die gleiche Weise können Sie die Tabelle aus der Zwischenablage in eine beliebige bearbeitbare Liste in einer beliebigen Form einfügen:
Bild

Eine solche Gelegenheit ist oft eine Alternative zur Entwicklung spezialisierter Importe.

Tabelleneinstellung


In jeder Liste können Sie einige seiner Parameter ändern:
Bild

Sie können die Zusammensetzung der Spalten, ihre Größen, Überschriften, Masken usw. ändern. Sie können die Tabelleneinstellungen sowohl für den aktuellen Benutzer als auch für alle Benutzer speichern (sofern der aktuelle Benutzer über die erforderlichen Rechte verfügt).

Beachten Sie die Option Seitengröße. Damit können Sie das am Anfang des Artikels beschriebene „Fenster“ vergrößern oder verkleinern. Beispielsweise können Sie anstelle von automatischen 50 Einträgen einen größeren Wert angeben. Dann wird eine größere Datenmenge auf den Client und den Server heruntergeladen, Anforderungen treten jedoch seltener auf. Wenn Sie den Wert dieses Parameters auf 0 setzen, wird er aus jeder dynamischen Liste normalisiert, dh, alle Einträge in der Liste werden immer gelesen. Die Größe des Fensters kann auch direkt im Code mit dem Parameter pageSize der Anweisung DESIGN angegeben werden.

Export nach Excel


Für jede Liste ist es möglich, alle Datensätze in Excel hochzuladen. Klicken Sie dazu einfach auf die folgende Schaltfläche:
Bild

Hierbei werden die aktuellen Auswahlen, Sortierungen sowie nur die in den Tabelleneinstellungen angegebenen sichtbaren Spalten berücksichtigt.

Schwenkbar


Standardmäßig wird jede Liste als Tabelle angezeigt. Es besteht jedoch die Möglichkeit, in einen speziellen Anzeigemodus zu wechseln, in dem der Benutzer verschiedene Berichte und Diagramme erstellen kann:
Bild


Bei einer geringen Anzahl von Einträgen in der Liste werden die Daten direkt auf dem Client verarbeitet. Sobald die Datenmenge einen bestimmten Schwellenwert überschreitet, werden automatisch generierte Datenbankabfragen auf dem Server verwendet, um die Daten zu gruppieren.

Alternative


Eine vernünftige Frage stellt sich. Lösen des Problems beim Bearbeiten dynamischer Listen auf Plattformen, auf denen diese Funktion nicht unterstützt wird. In den meisten Fällen wird eine einfache Liste erstellt, in der der Benutzer gezwungen ist, die Anzahl der Einträge durch eine Auswahl zu begrenzen (z. B. Filter nach Kategorie, Anbieter oder anderen verwandten Verzeichnissen anzugeben).

Dieser Ansatz weist jedoch ein ernstes Problem auf. Selbst bei einer festgelegten Auswahl kann nicht garantiert werden, dass eine erhebliche Anzahl von Datensätzen nicht in der Stichprobe enthalten ist. Es ist unmöglich, die Anzahl der erhaltenen Werte im Voraus zu berechnen, da die Komplexität einer solchen Operation häufig direkt mit der Komplexität des Erlangens aller Daten vergleichbar ist. Dementsprechend wird in einigen Fällen eine große Anzahl von Einträgen in die Liste aufgenommen, was zu einem hohen Ressourcenverbrauch auf dem Server oder Client sowie zu einer signifikanten Abnahme der Leistung führt.

Fazit


Das Implementieren einer dynamischen Liste in der modernen Entwicklung ist nicht die einfachste Aufgabe, da sowohl der Client- als auch der Serverteil beteiligt sind. Es gibt weltweit eine ganze Reihe von Open-Source-Bibliotheken mit einer offenen Lizenz, mit denen Sie diese Funktionalität schnell und bequem implementieren können.

In der offenen und kostenlosen lsFusion-Plattform werden dynamische Listen in mehreren Codezeilen erstellt und bieten dem Benutzer eine Vielzahl von Möglichkeiten, mit ihnen zu arbeiten. In Kombination mit der Möglichkeit, solche Listen zu bearbeiten, können Sie auf der Plattform schnell mit Dokumenten in Hunderttausenden von Zeilen arbeiten, die Auswahl von Datensätzen in Dokumenten komfortabel organisieren, Gruppenänderungen an Verzeichnissen vornehmen und vieles mehr.

Die Verwendung dynamischer Listen kann den Verbrauch von Prozessorzeit und Speicher auf dem Server und dem Client erheblich reduzieren, indem mit einem begrenzten Datensatz gearbeitet wird, und die Belastung des Kommunikationskanals zwischen dem Server und dem Client verringern. Aufgrund dieser hohen Effizienz führen fünf der acht größten Einzelhandelsketten ihre operativen Hauptaktivitäten mit Lösungen aus, die auf der lsFusion-Plattform in Belarus basieren.

Source: https://habr.com/ru/post/de484648/


All Articles