felberbauer_0

GWT: CellTable mit Pagination von serverseitigen Daten

Googles Framework GWT bietet mit der CellTable bereits eine Komponente für tabellarische Daten an, die sowohl Pagination als auch Sortierung out-of-the-box unterstützt. Die Implementierung des GWT Showcase unter Verwendung von SimplePager und ListDataProvider ist allerdings clientseitig ausgelegt und daher für große Datenmengen, insbesondere wenn ältere Browser unterstützt werden müssen, leider unbrauchbar. Aus diesem Grund haben wir eine Lösung implementiert, die die CellTable verwendet, jedoch immer nur so viele Daten vom Server lädt, wie der Benutzer im Moment sehen möchte.

Tabellen und Listen sind für viele User Interfaces unerlässlich und werden unter anderem zum Suchen und Filtern von Daten verwendet. Dabei sollten die Spalten einer zeitgemäßen Tabellenkomponente sortierbar sein und die Lade- und Reaktionszeit muss für den Benutzer gering gehalten werden. GWT bietet mit der CellTable eine umfangreiche Tabellenkomponente. Mittels SimplePager lässt sich die Tabelle schnell um Pagination erweitern. Zusätzlich steht Sortierfunktionalität der Spalten mit dem ListDataProvider für in-memory Listen oder dem AsyncDataProvider zur Verfügung (siehe hier)

Schnelle Reaktionszeit von User Interfaces 

Diese Lösung arbeitet jedoch rein clientseitig, was bedeutet, dass bereits beim Initialisieren der Tabelle alle Daten am Client zur Verfügung stehen müssen. Dies führt jedoch bei großen Datenmengen zu erheblichen Ladezeiten am Client, bedingt durch Übertragungszeiten vom Server und zusätzlich der Verarbeitungsdauer am Client. Nehmen wir als Beispiel eine Tabelle, die alle Benutzer des Systems auflisten soll, so wird schnell klar dass eine clientseitige Lösung mit steigender Benutzeranzahl sehr bald zu nicht vertretbaren Ladezeiten führen wird. 

Da die angeführte Lösung für mehrere tausend Benutzer nicht skalierbar ist, haben wir bei Cenarion eine eigene Tabellenkomponente unter Verwendung der bereits erwähnten CellTable implementiert. Diese unterstützt sowohl Pagination als auch Sortierung, lädt jedoch immer nur die Anzahl der Datensätze vom Server nach, die in der Pager-Komponente ausgewählt ist.  

Die Tabellenkomponente

Die Tabellenkomponente ist für die Anzeige der Daten und die Funktionalität des User Interface verantwortlich. So stellt sie den Pager zur Verfügung und reagiert auf Userinteraktionen wie Blättern, Ein- und Ausblenden oder Sortieren von Spalten. Darüber hinaus stellt sie eine Suche über definierbare Spalten der Tabelle zur Verfügung, kapselt die Parameter für Serveranfragen und zeigt die Ergebnisse vom Server an. Dabei werden die Benutzereinstellungen wie die aktuelle Seite, Seitengröße, die Spalte nach der sortiert werden soll, die Sortierreihenfolge, eine Liste von sichtbaren Spalten und die vom Benutzer eingegebenen Suchparameter an den Server übertragen und pro Benutzer in der Datenbank gespeichert. Dadurch bleiben die genannten Einstellungen erhalten, wenn der Benutzer zu einem späteren Zeitpunkt erneut auf die Seite navigiert. 

Pager

Der von GWT zur Verfügung gestellte SimplePager beherrscht bereits die grundlegenden Anforderungen an eine Pager-Komponente. Interaktionen des Benutzers wie z.B. das Wechseln der aktuellen Seite oder der Seitengröße, aber auch das Sortieren nach einer Spalte lösen eine Aktualisierung der Tabelle aus. Dies ist für uns problematisch, da wir – wie bereits erwähnt – die Benutzereinstellungen speichern und beim Initialisieren der Tabelle wiederherstellen. Das bedeutet, dass durch das programmatische Setzen der Einstellungen des Pagers und der Sortierspalte und -reihenfolge wiederum eine neue Serveranfrage ausgelöst werden würde, was schlussendlich zu einer Endlosschleife führt. Aus diesem Grund haben wir einen eigenen Pager geschrieben. Dieser leitet zwar ebenfalls von AbstractPager ab, hat jedoch keine direkte Verbindung zur Tabellenkomponente mehr.  Auf diese Weise können wir die Ressourcen wie Stylesheets und Icons von AbstractPager nutzen, behalten dabei aber die Kontrolle über das Verhalten bei Userinteraktionen. 

Fazit

Unsere Tabellenkomponente vereint die von der CellTable angebotenen Features mit den Vorteilen von Pagination, ohne dabei immer alle Daten auf den Client übertragen und dort halten zu müssen. Da sich die Anzahl der zu übertragenden Datensätze auf die im Pager eingestellte reduziert, bleibt die Ladezeit am Client konstant und sichert so die Skalierbarkeit bei wachsenden Datenmengen. 

Hattest du selbst schon mit den beschriebenen Problemstellungen bezüglich Tabellen und Pagination in GWT zu tun? Hinterlasse uns doch einen Kommentar, in dem du uns deine Problemlösung skizzierst! 

Florian Felberbauer
(Software Developer)