【问题标题】:jqgrid toolbar search or external search featurejqgrid 工具栏搜索或外部搜索功能
【发布时间】:2012-02-13 10:17:48
【问题描述】:

您好,我正在使用 jqgrid 在 .net MVC 3.0 C# 应用程序中加载一些数据。

有一个材质网格需要在大约 6 个不同的地方加载。他们都是一样的。该网格列出了大约 8700 种商品的定价和详细信息。

我遇到的问题是“成本”和“价格”两列的计算是从数据库执行的。这两列使网格加载极其缓慢。

我们使用的材料测试清单最初有大约 730 个项目。第一次没有某种优化,网格需要大约 1 分 30 秒才能完全加载。更改后,这下降到大约 4 秒,这是可以接受的。

我们现在正在处理将用于材料的真实列表,该列表包含 8500 多个项目。初始加载后,手表加载 8500 件商品大约需要 2 分钟。

这真的是不可接受的,所以我认为最好的解决方案是让搜索工具栏功能或外部搜索成为加载项目但仅加载搜索结果项目的功能。

所以我想看到的是,在初始页面加载后,网格是空的,只有在搜索完成后才会被填充,并且只显示搜索结果。

如果可能的话,最好使用搜索工具栏功能来做到这一点。这已经正常工作,但在初始长负载之后。

非常欢迎任何建议。我不是最初的程序员,只是想获取一些信息,所以如果可能的话,我不必为我的开发人员支付谷歌搜索费用。

感谢您的宝贵时间,如果需要当前代码的示例,请告诉我是否有帮助,或者如果我需要的话,您是否可以提供一些示例代码,

服务器端代码:

 public ActionResult EstimateMaterialAddGridData(string sidx, string sord, int page, int rows)
    {

        IQueryable<Material> mats;
        mats = Material.Find(x => x.OwnerId == UserAccount.GetOwnerId && x.isDeletedFromCatalog == false).AsQueryable();

        int pageIndex = page - 1;
        int pageSize = rows;
        int totalRecords = mats.Count();
        int totalPages = (int)Math.Ceiling((float)totalRecords / (float)pageSize);
        var jsonData = new
        {
            total = totalPages,
            page = page,
            records = totalRecords,
            rows = (
                from sub in mats
                select new
                {
                    i = sub.Id,
                    cell = new string[] {
                        sub.Id.ToString(),
                        sub.Id.ToString(),
                        sub.Id.ToString(),
                        sub.ProductCode,
                        sub.Description, 
                        sub.Units,
                        sub.Categories,
                        sub.UnitCost.ToString(),
                        sub.Price.ToString()
                    }
                }
            ).ToArray()
        };

        return Json(jsonData);
    }

JS网格代码`jQuery(document).ready(function () { var grid = jQuery("#mgrid");

grid.jqGrid({
    url: '/Material/EstimateMaterialAddGridData',
    datatype: 'json',
    mtype: 'POST',
    colNames: ['Id', '','View/Edit',  'Product Code', 'Description', 'Units', 'Categories', 'Cost', 'Price'],
    colModel: [
        { name: 'Id', index: 'Id', key: true, hidden: true, editrules: { edithidden: true} },
        { name: 'Add', index: 'Add', sortable: false, width: 50,search:false, resizable: false, editable: false, align: 'center', formatter: formatLink, classes: 'not-editable-cell' },
        { name: 'Open', index: 'Open', sortable: false, width: 90,search:false, resizable: false, editable: false, align: 'center', formatter: formatLinkNew, classes: 'not-editable-cell' },
        { name: 'ProductCode', index: 'ProductCode', sorttype: 'text',search:true, width: 100, resizable: false },
        { name: 'Description', index: 'Description', sorttype: 'text',search:true, width: 275, resizable: false },
        { name: 'Units', index: 'Units', sorttype: 'text', width: 75,search:true, resizable: false },
        { name: 'Categories', index: 'Categories', sorttype: 'text',search:true, width: 300, resizable: false, editable: false,  },
        { name: 'UnitCost', index: 'UnitCost', sorttype: 'float', width: 75,search:true, align: 'right', resizable: false, editable: false, formatter: 'currency' },
        { name: 'Price', index: 'Price', sorttype: 'float', width: 75, search:true,align: 'right', resizable: false, editable: false, formatter: 'currency' },
    ],
    pager: '#mpager',
    height: '100%',
    rowNum: 10,
    rowList: [10, 20, 50, 100],
    sortname: 'Id',
    sortorder: 'desc',
    sortable: true,
    loadonce: true,
    ignoreCase: true,
    viewrecords: true,
    caption: 'Material',
    cellEdit: false,
    hidegrid: false,
    viewrecords: true,

});

grid.jqGrid('navGrid', '#mpager',
    { resize: false, add: false, del: false, search: true, refresh: true, edit: false, alerttext: 'Please select an material' }
).jqGrid('navButtonAdd', '#mpager',
    { title: "Create New Material Catalouge", buttonicon: "ui-icon-plus", onClickButton: newMaterial, position: "First", caption: "" });`

【问题讨论】:

  • 能否包含目前使用 jqGrid 的代码?您能否提供有关“成本”和“价格”列的实施的更多信息。我不明白为什么你应该对列有任何问题。产生列值的 SELECT 是不是太慢了?

标签: c# javascript asp.net-mvc jqgrid


【解决方案1】:

我可以将您转发到以下两个旧答案:thisthis。答案包含演示项目,演示如何使用 jqGrid 中的搜索工具栏。

我应该提到以下可以显着提高 jqGrid 性能的事情

  • 您应该始终使用 jqGrid 的gridview: true 选项。在我看来,它应该是 jqGrid 中的默认选项。
  • 您应该明确地使用服务器端分页。我认为一次向用户显示 8500 多个(或 730 个)项目是没有意义的。没有监视器可以显示这些项目,也没有用户可以从这么多项目中吸收信息。用户真正需要的是能够对数据进行智能过滤——您自己决定采用的方式。我主要使用searching toolbaradvanced searching中的网格过滤组合,帮助高级用户构建更复杂的搜索过滤器。此外,您可以考虑将一些常用的过滤器保存在预定义的命名过滤器模板中。您可以在the official demo page 的“搜索”/“搜索模板”下找到过滤器模板的示例。另一种方法是使用外部过滤器。在the answer 中,您将找到可以帮助您的实现细节。
  • 如果你想阻止第一次加载网格,你可以使用datatype: 'local',它会跳过对服务器的任何请求。要激活与服务器的通信,您可以根据需要将datatype 更改为'json''xml'。例如,您可以将$(this).jqGrid('setGridParam', {datatype: 'json'}); 直接放在loadComplete 内。

【讨论】:

  • ok 会调查一下,看看它是否可行。只是为了澄清我的网格设置为每页仅显示 20 个结果。即使它是这样设置的,整个 8500 多个项目都在后台加载,所以当我转到第 2、3、4 页时......它们都已经加载了。如果在我输入搜索词时更改为每页仅加载 20 个,它将仅查看已加载的 20 个项目还是仍会查看所有 8300 个项目?
  • @user1206514:分页和排序等搜索应该在服务器端实现。服务器获取当前过滤器作为filters 参数。您应该将SELECTWHERE 部分构造到数据库,并像以前一样只将请求的页面返回给客户端。请求的页面由pagerows 参数标识。如果您按照前一个查询的结果(获取另一个页面)的场景,完整的 SELECT(没有分页)的数据可以缓存在数据库中。所以选择另一个页面通常很快。
  • @user1206514:无论如何,如果您使用服务器端分页、排序和过滤,您通常每页有 WHERE 部分,您将免受任何 SQL 注入攻击。因此,您可以真正实现所有工作,不仅快速而且安全。
  • 谢谢 Oleg 我刚刚获得了一份服务器端代码和 javascript 代码的副本,如果我能采纳您的建议,或者在您看到我的建议后,我将不胜感激。它仍然适用的代码。
  • @user1206514:在您的代码中有一个重要错误:您使用i = sub.Id 而不是id = sub.Id。我建议您阅读the answeranother one,其中包含更新的代码,您可以下载并采用到您的项目中。