使用远程数据使用KendoUI和ServiceStack进行分页

时间:2014-10-22 21:51:25

标签: kendo-ui servicestack kendo-grid kendo-asp.net-mvc

是否可以使用ServiceStack进行服务器端分页,并通过带有KendoUI网格的JSON / AJAX使用它?我有大量需要分页的数据(30,000多行)。我需要电线上最小的有效载荷。 Kendo网格的所有示例都显示了客户端设置的分页参数,但ServiceStack似乎没有使用它们。这让我担心一切都将通过网络发送。这是在ASP.NET MVC4应用程序中运行。

1 个答案:

答案 0 :(得分:3)

你说得对,大多数KendoUI示例都使用客户端分页,它首先通过网络发送整个数据集。几个月前我遇到了这个问题,并最终选择了一种不同的整体方法,但我有所拥有的。

您可以采取以下两种基本方法之一:

  1. 使用DataSource设置配置KendoUI transport,将KendoUI查询更改为与ServiceStack更加协作的查询。
  2. 配置"某事"在ServiceStack中了解KendoUI分页。
  3. 我使用全局请求过滤器使用#2。这是不完整的代码,但其想法是处理分页,排序和过滤。您可以保持PagePageSizeSkipTake参数,然后手动应用分页。

    首先,DTO。对于任何ServiceStack DTO,也从该基类继承。我知道这种情况在Mythz(非常有效)opinion on DTO design的情况下过得很快,但这种方法在其他方面不会起作用。

    public class KendoQueryBase : IKendoFilter, IKendoSort, IKendoPaged
    {
        public FilterTerm Filter { get; set; }
        public List<SortTerm> Sort { get; set; }
    
        public int? Page { get; set; }
        public int? PageSize { get; set; }
        public int? Skip { get; set; }
        public int? Take { get; set; }
    }
    

    然后使用全局请求过滤器将请求转换为可由ServiceStack解释的格式。同样,如果您只是进行分页,则可能不需要这样做。它也不完整,但显示了一个不错的起点。

    class KendoQueryPlugin : IPlugin
    {
        public void Register(IAppHost appHost)
        {
            appHost.GlobalRequestFilters.Add((req, resp, dto) =>
            {
                if (dto is KendoQueryBase)
                {
                    KendoQueryBase qb = dto as KendoQueryBase;
                    if (qb.Sort == null) qb.Sort = new List<SortTerm>();
                    Dictionary<string, string> qs = req.QueryString.ToDictionary();
    
                    // Create the Sort Terms
                    var i = 0;
                    while (qs.ContainsKey("sort[{0}][field]".Fmt(i)))
                    {
                        qb.Sort.Add(new SortTerm()
                        {
                            Field = qs["sort[{0}][field]".Fmt(i)],
                            Dir = qs["sort[{0}][dir]".Fmt(i)]
                        });
                        i++;
                    }
    
                    i = 0;
                }
            });
        }
    }
    

    修改

    为了进一步解决分页问题,​​我还编写了一个帮助扩展,利用ServiceStack.OrmLite库并将分页插入SqlExpression

    public static class PagingExtensions
    {
        public static SqlExpression<T> Page<T>(this SqlExpression<T> exp, int? page, int? pageSize)
        {
            if (!page.HasValue || !pageSize.HasValue)
                return exp;
    
            if (page <= 0) throw new ArgumentOutOfRangeException("page", "Page must be a number greater than 0.");
            if (pageSize <= 0) throw new ArgumentOutOfRangeException("pageSize", "PageSize must be a number greater than 0.");
    
            int skip = (page.Value - 1) * pageSize.Value;
            int take = pageSize.Value;
    
            return exp.Limit(skip, take);
        }
    }
    

    您可以将它与上述DTO模式一起使用,如下所示:

    if (!request.Page.HasValue) request.Page = 1;
    if (!request.PageSize.HasValue || request.PageSize < 0 || request.PageSize > 100)
        request.PageSize = 10;
    
    var exp = Db.From<Your Database Object>
    ....
    var results = Db.Select<YourDTO>(exp.Page(request.Page, request.PageSize)),