Lösungsansatz 1: Kendo UI Grid, speichern der Filter- und Sortiereinstellungen

29 Juli 2014
Simon Steinkrüger

Das Kendo UI Grid von Telerik zeigt tabellarische Daten und bietet umfangreiche Unterstützung für die Interaktion mit Daten, einschließlich Paging, Sortierung, Gruppierung und Auswahl. Das Grid ist ein leistungsstarkes Widget mit vielen Konfigurationsmöglichkeiten. Es kann zu lokalen oder JSON-Daten auf Remote-Daten mit dem Kendo Datasource-Komponente gebunden werden. Weitere Informationen gibt bei den Demos für Telerik Kendo UI unter http://demos.telerik.com/kendo-ui/grid/index

Leider bietet das Grid standardmäßig keine Möglichkeit, Filter- und Sortiereinstellungen zwischen zu speichern, um beispielsweise dem Benutzer die Möglichkeit zu geben, seine Einstellungen während seiner Sitzung beizubehalten. D.h. bei einem Wechsel zwischen verschiedenen Seiten müssen die gewünschten Grid-Einstellungen immer wieder neu vorgenommen werden.

Eine standarmäßige Gridkonfiguration sieht wie folgt aus:

 
  1. @(Html.Kendo().Grid<TelerikWebApplication.Models.Product>()
  2. .Name("GridProducts")
  3. .DataSource(dataSource=>dataSource// Konfigurieren der Grid DataSource
  4. .Ajax()// Spezifieren, dass AJAX benutzt wird
  5. .Read(read=>read.Action("Products_Read","Home"))// Setzen der Action-Methode, welche die Grid-Daten im JSON-Format zurückliefert
  6. )
  7. .Columns(columns=>
  8. {
  9. // Erzeugen einer Spalten welche an das ProductID property gebunden ist
  10. columns.Bound(product=>product.ProductID);
  11. // Erzeugen einer Spalten welche an das ProductName property gebunden ist
  12. columns.Bound(product=>product.ProductName);
  13. // Erzeugen einer Spalten welche an das UnitsInStock property gebunden ist
  14. columns.Bound(product=>product.UnitsInStock);
  15. // Erzeugen einer Spalten welche an das Categorie property gebunden ist
  16. columns.Bound(product=>product.Categorie);
  17. })
  18. .Pageable()// Paging aktivieren
  19. .Sortable()// Sortieren aktivieren
  20. .Filterable()// Filtern aktivieren
  21. )

Die Read-Methode für das Grid lautet folgendermaßen:

 
  1. publicActionResultProducts_Read([DataSourceRequest]DataSourceRequestrequest)
  2. {
  3. List<Product>productList=this.GetProductList();
  4. DataSourceResultresult=productList.ToDataSourceResult(request);
  5. returnJson(result);
  6. }

Der request-Parameter beinhaltet alle nötigen Informationen, um die Inhalte des Grids festzulegen. Dieser Parameter wird der Kendo-eigenen Methode ToDataSourceResult übergeben, welche aus den zuvor geholten Daten und dem request-Parameter den Gridinhalt generiert.

Die Kendo-eigene Klasse DataSourceRequest beinhaltet alle geposteten Parameter und ist folgendermaßen aufgebaut:

 
  1. publicclassDataSourceRequest
  2. {
  3. publicDataSourceRequest();
  4. publicIList<Kendo.Mvc.AggregateDescriptor>Aggregates{get;set;}
  5. publicIList<Kendo.Mvc.IFilterDescriptor>Filters{get;set;}
  6. publicIList<Kendo.Mvc.GroupDescriptor>Groups{get;set;}
  7. publicintPage{get;set;}
  8. publicintPageSize{get;set;}
  9. publicIList<Kendo.Mvc.SortDescriptor>Sorts{get;set;}
  10. }

Die einfachste Möglichkeit, die eingestellten Filter- und Sortiereinstellungen beim nächsten Seitenaufruf wieder zu verwenden, ist das request-Objekt in der Session abzulegen und beim nächsten Laden der Seite wieder zu holen. D.h. beim Aufruf der Index-Methode setzen wir einen Schalter, welches bekannt gibt, dass es sich um einen Seitenneuaufbau handelt.

 
  1. publicActionResultIndex()
  2. {
  3. Session["NewPageLoad"]=true;
  4. returnView();
  5. }

In der Product_Read-Methode wiederum wird geprüft, ob es sich um ein Neuladen der Seite handelt. Ist das der Fall, wird ggf. ein vorher gesetztes request-Objekt wieder geholt und als aktueller request wieder verwendet. Gleichzeitig wird der in der Index-Methode gesetzte Schalter wieder zurückgesetzt.

Beim nächsten Filter- oder Sortiervorgang wird nun der übergebene Request in der Session abgelegt.

 
  1. publicActionResultProducts_Read([DataSourceRequest]DataSourceRequestrequest)
  2. {
  3. // Wurde die Seite gerade neu geladen? Wenn ja, dann wird ein evtl. abgelegtes reqeust-Objekt geholt
  4. if(Session["NewPageLoad"]!=null&&(bool)Session["NewPageLoad"]==true)
  5. {
  6. Session["NewPageLoad"]=false;
  7. if(Session["PreservedRequest"]!=null)
  8. {
  9. request=(DataSourceRequest)Session["PreservedRequest"];
  10. }
  11. }
  12. // Ansonsten werden die gerade geposteten Einstellungen in der Session gespeichert
  13. else
  14. {
  15. Session["PreservedRequest"]=request;
  16. }
  17. DataSourceResultresult=this.GetProductList().ToDataSourceResult(request);
  18. returnJson(result);
  19. }

Das funktioniert so weit wie gewünscht, nur was ist wenn eine Anwendung dutzende oder gar hunderte von Grids enthält? Dann müssten wir o.g. Vorgehen in jeder Index- und Read-Methode anwenden, was ein sehr mühseliges und schwer wartbares Verfahren wäre.

Wie das auf eine generische Art und Weise zu bewerkstelligen ist, werden wir in PART 2  dieses Posts behandeln.