Preserving Kendo Grid state

I have a grid with server operations flag set to false. I can sort and filter on the columns (now I have only one) of the grid:

@(Html.Kendo().Grid<Models.ItemModel>()
            .Name("Grid")
            .DataSource(dataSource => dataSource
                .Ajax()
                .ServerOperation(false)
                .Model(model =>
                {
                    model.Id(r => r.Id);
                    model.Field(r => r.Name)
                         .Editable(false).DefaultValue("");
                })
                .Read(read => read
                    .Action("Grid_Read", "Home")
                    .Type(HttpVerbs.Get)))
            .Columns(columns =>
            {
                columns.Bound(r => r.Id).Hidden();
                columns.Bound(r => r.Name);
            })
            .Sortable()
            .Filterable()
            .Scrollable(scrollable => scrollable.Virtual(true))
            .Resizable(resizable => resizable.Columns(true))
            .AutoBind(false))

My goal is to make sure that all sortings and filterings are preserved if the page is reloaded. To achieve this, I obtain a grid state in the form of a JSON object which I store in the browser's localStorage. To accomplish this I created two javascript functions. One to save the state:

function saveGridState(gridId) {

        var grid = this.data("kendoGrid"),
            dataSource = grid.dataSource,
            state = {
                columns: grid.columns,
                page: dataSource.page(),
                pageSize: dataSource.pageSize(),
                sort: dataSource.sort(),
                filter: dataSource.filter(),
                group: dataSource.group()
            },

            json = JSON.stringify(state);

        localStorage[gridId] = json;
}

and the second one to retrieve it and apply to the grid:

function loadGridState(gridId) {

      var json = localStorage[gridId];

      if (!json) { return; }

      var grid = $('#'+gridId).data('kendoGrid'),
          gridState = JSON.parse(json);

      grid.dataSource.sort(gridState.sort);
      grid.dataSource.filter(gridState.filter);
      grid.dataSource.group(gridState.group);
      grid.dataSource.page(gridState.page);
      grid.dataSource.pageSize(gridState.pageSize);
 }

In the razor view I load the state, apply it to the grid and bind dataBound event to saving an updated stated whenever a sorting or filtering has changed.

<script>

 loadGridState('grid');
 $('#grid').data('kendoGrid').data('kendoGrid').dataSource.read();
 $('#grid').data('kendoGrid').dataSource.bind('dataBound',function(){
    saveGridState('grid');
});
</script>

The mechanism works fine except one small undesirable artifact in the behavior that I cannot get rid off. Namely, I notice that the Read action of the grid is always called twice. The first time when the page is loaded and the second time when I call loadGridState.

My thinking was, since the server operations set to false, applying paging, filtering and sorting, should not perform an AJAX call. But it still does.

Any suggestions would be greatly appreciated.


The Kendo demo page (http://demos.telerik.com/kendo-ui/grid/persist-state) has an example of persisting state:

localStorage["kendo-grid-options"] = kendo.stringify(grid.getOptions());

Similarly, to load state:

var options = localStorage["kendo-grid-options"];
if (options) {
   grid.setOptions(JSON.parse(options));
}

This should be all you need. In the context of your custom functions, they would look similar to:

function saveGridState(gridId) {
   var grid = $('#' + gridId).data("kendoGrid");
   localStorage[gridId] = kendo.stringify(grid.getOptions());
}

function loadGridState(gridId) {
   var grid = $('#' + gridId).data("kendoGrid");
   var options = localStorage[gridId];
   if (options) {
      grid.setOptions(JSON.parse(options));
   }
}

To do this as part of the initial read action, you may need to use the Data method to specify a JavaScript method which is called that can retrieve the stored settings and pass it to the controller method as a DataSourceRequest object.

Your Read method would look like

.Read(read => read
     .Action("Grid_Read", "Home")
     .Type(HttpVerbs.Get)
     .Data("getGridState")
))

The getGridState would look similar to:

function getGridState() {
   var grid = $('#' + gridId).data("kendoGrid");
   var options = localStorage[gridId];
   if (options) {
      return { request: JSON.parse(options)) };
   }

   return { request: "" };
}

Finally, the controller method would look similar to this:

public ActionResult Grid_Read([DataSourceRequest]DataSourceRequest request)
{
     ...
     DataSourceResult result = res.ToDataSourceResult(request);
     return Json(result, JsonRequestBehavior.AllowGet);
}
链接地址: http://www.djcxy.com/p/70436.html

上一篇: Kendo UI Grid:如何根据位值更改单元格文本

下一篇: 保留Kendo网格状态