Kendo网格服务器端分组

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Kendo网格服务器端分组相关的知识,希望对你有一定的参考价值。

我正在使用Asp net 5,NHibernate 3.3和Kendo UI MVC包装器来生成网格以呈现客户订单表。数据库中已经有很多订单,数量也在不断增长。所以我决定使用服务器端分页来避免从数据库中获取所有订单。据我所知,你不能手动分页并委托过滤,排序和分组到ToDataSourceResult方法。无论是全有还是全无。因此,我试图实施所谓的'custom binding'。在我进行分组之前没问题。我需要先进行分组,然后在组内部进行排序,然后提取特定页面的数据以及所有这些数据而不将所有数据加载到内存中。我的代码是这样的(我把它全部放在一块以简化阅读):

var orderList = CurrentSession.QueryOver<Order>();

// Filtering. Filter is a search string obtained from DataSourceRequest
var disjunction = new Disjunction();
disjunction.Add(Restrictions.On<Order>(e => e.Number).IsLike("%" + filter + "%"));
disjunction.Add(Restrictions.On<Order>(e => e.Customer).IsLike("%" + filter + "%"));
orderList = orderList.Where(disjunction);

// Sorting. sortColumn is also from DataSourceRequest
switch (sortColumn)
{
        case "Number":
            orderList = orderList.OrderBy(x => x.Number).Desc;
            break;
        case "GeneralInfo.LastChangeDate":
            orderList = orderList.OrderBy(x => x.LastChangeDate).Desc;
            break;
        default:
            orderList = orderList.OrderBy(x => x.Number).Desc;
            break;
     }
}

// Total is required for kendo grid when you do paging manually
var total = orderList.RowCount();


var orders = orderList
    .Fetch(x => x.OrderGoods).Eager
    .Fetch(x => x.OrderComments).Eager
    .Fetch(x => x.Documents).Eager
    .Fetch(x => x.Partner).Eager
    .Skip((request.Page - 1)*request.PageSize).Take(request.PageSize).List();

我很乐意就如何在这里添加分组提出任何建议。

答案

几个月来,我一直在使用带有Kendo Grid的Kendo DataSource来计算服务器端分组。分页,排序和过滤相当容易。但无论出于何种原因,Telerik都没有为像分组这样的关键LOB流程提供足够的支持文档。我很高兴你发布了这个问题,所以我有机会分享我的代码。

解决方案

基本上,解决方案归结为了解2个关键部分,并且可以在以下示例项目中查看它们:https://www.dropbox.com/s/ygtk8rwl1hwjvth/KendoServerGrouping.zip?dl=0

您正在下载的Visual Studio(2012 | 2013)解决方案中有一个Web应用程序项目,其中包含对Kendo.Mvc库的引用。您可以从Telerik的控制面板安装程序下载最新的ASP.NET二进制UI。安装后,二进制文件将位于以下Windows目录中:C: Program Files(x86) Telerik UI for ASP.NET MVC [Telerik发行版] wrappers aspnetmvc Binaries [您的MVC版本] Kendo .Mvc.dll。

注意:我的解决方案使用Telerik的MVC传输机制,该机制提供完整的服务器端分页,过滤,排序,最值得注意的是分组。但是,我使用纯javascript来配置Kendo DataSource而不是MVC包装器。不过,我最近在Telerik的文档中显示了found a link,它显示了Razor / ASPX中的MVC包装器声明。

服务器魔术

基本上,魔术的第一部分是以下服务器端代码,驻留在KendoServerGrouping.Web Controllers目录中的示例WebApi控制器中:

    [System.Web.Http.AcceptVerbs("GET", "ASPNETMVC-AJAX")]
    public Kendo.Mvc.UI.DataSourceResult GetAllAccounts([System.Web.Http.ModelBinding.ModelBinder(typeof(WebApiDataSourceRequestModelBinder))] Kendo.Mvc.UI.DataSourceRequest request)
    {
        var kendoRequest = new Kendo.Mvc.UI.DataSourceRequest
        {
            Page = request.Page,
            PageSize = request.PageSize,
            Filters = request.Filters,
            Sorts = request.Sorts,
            Groups = request.Groups,
            Aggregates = request.Aggregates
        };

        // Set this to your ORM or other data source
        IQueryable accounts = dbContext.Accounts;

        /*
           The data source can even be a MongoDB collection using the
           .AsQueryable() extension and the MongoDB C# driver

           var accounts = collection.FindAllAs<Account>().AsQueryable();
        */

        var data = accounts.ToDataSourceResult(kendoRequest);

        var result = new DataSourceResult()
        {
            AggregateResults = data.AggregateResults,
            Data = data.Data,
            Errors = data.Errors,
            Total = data.Total
        };

        return result;
    }

这就是网格在用户与之交互时自动神奇地处理的四个服务器端操作中的任何一个。特别注意方法上方的AcceptVerbs属性;它必须包含“ASPNETMVC-AJAX”属性才能使DataSourceRequest输入参数正常工作。 ToDataSourceResult()是最近版本的Kendo.Mvc.dll库提供的扩展,我在前面指出过。

上面的代码将(据我所知)与任何IQueryable数据源一起使用,例如来自ORM的数据源(我已经测试过实体框架和Telerik数据访问/开放访问)。我也能够使用MongoDB C#驱动程序对MongoDB集合进行分组。但是,这是一个概念验证,并没有经过性能测试。

出于此示例的目的,WebAPI控制器中存在静态数据源以伪造IQueryable集合。当然,当您交换自己的数据源时,可以从第45-57行删除静态数据。

客户魔术

如果您将DataSource架构包装在以下JavaScript中,Kendo DataSource会自动从包含服务器端分页,过滤,排序和分组所有参数的网格传入专门的DataSourceRequest对象:

schema: $.extend(true, {}, kendo.data.schemas["aspnetmvc-ajax"], {
});

这可能是我追踪过的最难以捉摸的代码。几个月后,它与Telerik进行了十几次交流,让他们咳嗽起来。即使在那时,它也是纯粹的偶然机会。为什么在他们的文档中缺少这样一个关键的细微差别超出了我的范围。

仔细检查每个Kendo DataSource配置设置到index.html文件的下半部分。最重要的是,要注意不存在的东西,例如batchmvcTransport选项。包括后一个选项会以某种方式否定上述“aspnetmvc-ajax”架构属性。

在DataSource的parmaterMap函数中,请注意当 - 并且仅当 - 执行读取操作时,必须存在以下行:

return mvcTransport.parameterMap(options, operation);

在DataSource执行之前,您还需要确保在HTML中包含它:

<script src="//cdn.kendostatic.com/[Version]/js/kendo.aspnetmvc.min.js"></script>

最终结果

运行KendoServerGrouping.Web项目(index.html),如果一切顺利,网格将填充5个包含AccountId,AccountName,AccountTypeCode和CreatedOn字段的记录。如果将可见网格行数设置为2并按AccountTypeCode或CreatedOn分组,您将看到分组遍历分页,我相信这是您要查找的最终结果。

我希望示例项目能够正常运行并且非常适合您的情况。如果您有任何问题,请告诉我,我会尽力帮助您。

附:这是我给SO的第一篇文章,所以如果某些内容达不到SO标准,请放轻松。祝好运!

另一答案

我想在this jewel I found on Telerik's forums上添加@ aaron-jessen的答案:

$("#grid").kendoGrid({
  dataSource: {
    type: "aspnetmvc-ajax",  // If missing may cause NULL values in ApiController
  }
})

以上是关于Kendo网格服务器端分组的主要内容,如果未能解决你的问题,请参考以下文章

Kendo UI - 网格分页(服务器端)

在 Kendo Grid 中设置默认分组

Kendo Grid 在创建后不会使用新创建的 id 更新网格

在 Kendo UI 网格中控制组顺序

分页kendo网格客户端

Kendo Grid中的服务器端分页?