jqGrid使用JsonString-JsonReader实现服务器端排序分页过滤

时间:2012-03-29 19:03:22

标签: javascript jqgrid jqgrid-asp.net

我在ASP.NET MVC 3 Web应用程序中使用jqGrid(4.3.1)。

我有一个独特的情况(至少,我找不到解决方案)因为我从外部源提供我的数据 - 在分页片段中 - 所以我不能使用网格的url属性,但我仍然必须实现服务器端排序,分页和&过滤

我的计划是(一旦我解决了以下问题)使用onPaging,onSortCol和beginSearch方法回调Web服务并刷新回调中的网格数据。

数据以jqGrid可以使用的格式提供(我可以通过jsonReader选项轻松映射):

jsonReader: {
    repeatitems: false,
    root: "Rows",
    page: "Page",
    total: "TotalPages",
    records: "RecordCount",
    userdata: "FooterTotals",
    id: "ClaimId"
},

我通过datastr选项传入数据并将数据类型设置为'jsonstring'。

loadonce设置为false(我已经尝试过两种方式),我的rowNum设置为10.

当我进行初始调用时,会返回一个包含约900条记录的数据集,并且网格显示前10条记录,但是寻呼机忽略了“总数”& '记录'并认为我只有1页数据

根数据不被忽略(它显示10条记录)并且不会忽略用户数据(即页脚正确呈现)。所以网格有选择地忽略数据中的“总数”和“记录”数据。

我的问题是 - 使用数据类型:jsonstring和datastr(并将json提供给网格而不是使用url)禁止利用服务器端分页/排序/过滤的能力?

如果是的话,有没有办法完成我追求的目标?

请注意,如果我返回整个900计数记录集并将loadonce设置为true,那么一切正常,尽管是客户端。

我的整个jqGrid,供参考:

g.claims.LoadGrid = function (url, pagerDiv, grid, caption, drillData) {
    jQuery(grid).jqGrid({
        url: url,
        datastr: drillData != null ? drillData : g.claims.gridData,
        datatype: 'jsonstring',
        mtype: 'POST',
        ajaxGridOptions: { contentType: 'application/json; charset=utf-8' },
        serializeGridData: function (postData) {
            if (postData.filters === undefined) postData.filters = null;
            postData.quick = $("#quickSearchText").val();
            return JSON.stringify(postData);
        },
jsonReader: {
    repeatitems: false,
    root: "Rows",
    page: "Page",
    total: "TotalPages",
    records: "RecordCount",
    userdata: "FooterTotals",
    id: "ClaimId"
},
        colNames: ['ClaimId', 'Claim Reference', 'Status', 'Handler', 'Create Date', 'Division', 'Line Of Business', 'Policy Reference', 'Incurred Amount', 'Paid Amount'],
        colModel: [
                { name: 'ClaimId', index: 'ClaimId', width: 90, sorttype: 'integer', align: 'right', searchoptions: { sopt: ['cn', 'eq', 'ne']} },
            { name: 'ClaimRef', index: 'ClaimRef', width: 120, searchoptions: { sopt: ['cn', 'eq', 'ne']} },
            { name: 'Status', index: 'Status', width: 100, searchoptions: { sopt: ['cn', 'eq', 'ne']} },
            { name: 'Handler', index: 'Handler', width: 140, searchoptions: { sopt: ['cn', 'eq', 'ne']} },
            { name: 'CreateDateDisplay', index: 'CreateDateDisplay', width: 90, align: 'center', sorttype: 'date', formatter: 'date', formatoptions: { srcformat: 'M-d-Y', newformat: 'd-M-Y' }, editable: true, datefmt: 'd-M-Y',
                editoptions: { dataInit: g.claims.initDateEdit },
                searchoptions: { sopt: ['eq', 'ne', 'lt', 'le', 'gt', 'ge'], dataInit: g.claims.initDateSearch }
            },
            { name: 'Division', index: 'Division', width: 90, searchoptions: { sopt: ['cn', 'eq', 'ne']} },
            { name: 'LineOfBusiness', index: 'LineOfBusiness', width: 120, searchoptions: { sopt: ['cn', 'eq', 'ne']} },
            { name: 'PolicyRef', index: 'PolicyRef', width: 120, searchoptions: { sopt: ['cn', 'eq', 'ne']} },
            { name: 'IncurredAmount', index: 'IncurredAmount', width: 120, sorttype: 'currency', align: 'right', searchoptions: { sopt: ['cn', 'eq', 'ne']} },
            { name: 'PaidAmount', index: 'PaidAmount', width: 120, sorttype: 'currency', align: 'right', searchoptions: { sopt: ['cn', 'eq', 'ne']} }

            ],
        rowNum: 10,
        rowList: [10, 20, 30],
        pager: pagerDiv,
        loadonce: false,
        sortname: 'ClaimId',
        viewrecords: true,
        sortorder: "desc",
        height: 250,
        ignoreCase: true,
        loadui: 'disable',
        autowidth: true,
        caption: caption,
        sortable: true,
        shrinkToFit: false,
        footerrow: true,
        userDataOnFooter: true,
        gridview: false,
        loadComplete: function () {
            var filters, quick, i, l, rules, rule, iCol, $this = $(this);
            if (this.p.search === true) {
                filters = $.parseJSON(this.p.postData.filters);
                if (filters !== null && typeof filters.rules !== 'undefined' && filters.rules.length > 0) {
                    rules = filters.rules;
                    l = rules.length;
                    for (i = 0; i < l; i++) {
                        rule = rules[i];
                        iCol = g.GetColumnIndexByName($this, rule.field);
                        if (iCol >= 0) {
                            $('>tbody>tr.jqgrow>td:nth-child(' + (iCol + 1) + ')', this).highlight(rule.data);
                        }
                    }
                }
            }
            quick = $("#quickSearchText").val();
            if (quick !== null) {
                var colCount = g.GetColumnCount($this);
                for (i = 0; i < colCount; i += 1) {
                    $('>tbody>tr.jqgrow>td:nth-child(' + (i + 1) + ')', this).highlight(quick);
                }
            }
            return;
        },
        onSelectRow: function (id) {
            var ret = jQuery(grid).jqGrid('getRowData', id);
            alert(ret.ClaimRef);
            //_currentRequestId = ret.RequestId;
            //ShowRequest();
        },
        loadError: function (xhr, textStatus, errorThrown) {
            var errorMsg = xhr.responseText;
            var msg = "Some errors occurred during processing:";
            msg += '\n\n' + textStatus + '\n\n' + errorMsg;
            g.trackError(msg, document.URL, 0);
        }

    });
    jQuery(grid).jqGrid('navGrid', pagerDiv, { refresh: false, edit: false, add: false, del: false, search: false });
    //jQuery(grid).jqGrid('setFrozenColumns');
    jQuery(grid).jqGrid(
        'navButtonAdd',
        pagerDiv,
        {
            caption: "",
            buttonicon: "ui-icon-newwin",
            title: "choose columns",
            onClickButton: function () {
                $(this).jqGrid('columnChooser', {
                    done: function () {
                        $(grid).trigger("resize");
                    }
                });
            }
        }
    );

    jQuery(grid).jqGrid(
        'navButtonAdd',
        pagerDiv,
        {
            caption: "",
            buttonicon: "ui-icon-refresh",
            title: $.jgrid.nav.refreshtitle,
            onClickButton: function () {
                $(this).jqGrid('setGridParam', { datatype: 'json' });
                $(this).trigger('reloadGrid', [{ page: 1}]);
            }
        }
    );

    jQuery(grid).jqGrid('filterToolbar', {
        stringResult: true,
        searchOnEnter: false,
        defaultSearch: 'cn',
        beforeSearch: function () {
            var postedData = $(this).jqGrid('getGridParam', 'postData');
            g.claims.FilterPageSort(postedData);
            return false;
        }
    });
    jQuery(grid).fluidGrid({ example: "#gridParent", offset: 0 });
};

更新(Oleg的更多信息):

ajax调用一个控制器方法(其注释引用下面描述的类)。此方法遵循jqGrid JSON序列化postData结构(带有一些额外参数):

    [HttpPost]
    public ActionResult GetLagChart(int page, int rows, string sidx, string sord, bool _search, string filters, string quick)
    {
        var claims = WarehouseDataProvider.Instance.GetClaim(quick);

        //will eventually be passed in as jqGrid filters - not yet implemented
        var startPeriod = 201101;
        var endPeriod = 201112;

        //the return of this method is of type Chart - see below
        var lag = WarehouseDataProvider.Instance.GetLagChart(claims, startPeriod, endPeriod);


        var viewModel = new LagChartViewModel
                            {
                                LagChart = lag,
                                GridData = GetResults(claims, page, rows, sidx, sord)
                            };

        return this.JsonNet(viewModel);
    }

上面代码中提到的Chart类:

public class Chart
{
    public List<ColumnSeries> Series { get; set; }
    public List<string> Categories { get; set; }
}

public class ColumnSeries
{
    public string Name { get; set; }
    public List<object> Values { get; set; }
}

上面提到的jqGrid GridData类:

public class GridData<T>
{
    public int TotalPages { get; set; }
    public int Page { get; set; }
    public int RecordCount { get; set; }
    public List<T> Rows { get; set; }
    public object FooterTotals { get; set; }
}

示例将Json发布到Web服务(启用HttpPost的控制器):

{ “页面”:1, “行”:10, “SIDX”: “ClaimID的”, “SORD”: “递增”, “_搜索”:假, “过滤器”:空, “快”:“EXC “}

响应Ajax:

{
  "GridData": {
    "TotalPages": 92,
    "Page": 1,
    "RecordCount": 911,
    "Rows": [
      {
        "ClaimId": 229731,
        "ClaimRef": "XXX111345",
        "ClaimTitle": "title 1",
        "Status": "Claim - Finalised",
        "IncurredAmount": 0.00,
        "PaidAmount": 0.00,
        "Handler": "Person One",
        "Handler1": "Person One",
        "Handler2": "Person One",
        "Handler3": "Person One",
        "Division": "Person One",
        "Branch": null,
        "LineOfBusiness": "Wholesale Excess",
        "PolicyRef": "SFSF9090888",
        "CreateDateDisplay": "03-30-2012",
        "DateOfAdvice": "2009-06-01T00:00:00",
        "DateOfLoss": "2007-07-08T00:00:00",
        "LossPeriod": 200707,
        "DateOfFirstReserve": "2009-06-03T00:00:00",
        "AdviceLag": 695,
        "ReserveLag": 3
      },
      {
        "ClaimId": 229933,
        "ClaimRef": "EXC123488",
        "ClaimTitle": "Title 2",
        "Status": "Claim - Finalised",
        "IncurredAmount": 0.00,
        "PaidAmount": 0.00,
        "Handler": "Person Two",
        "Handler1": "Person Two",
        "Handler2": "Person Two",
        "Handler3": "Person Two",
        "Division": "Excess",
        "Branch": null,
        "LineOfBusiness": "Wholesale Excess",
        "PolicyRef": "NY676767777",
        "CreateDateDisplay": "03-30-2012",
        "DateOfAdvice": "2009-06-02T00:00:00",
        "DateOfLoss": "2006-01-01T00:00:00",
        "LossPeriod": 200601,
        "DateOfFirstReserve": "2009-06-18T00:00:00",
        "AdviceLag": 1249,
        "ReserveLag": 17
      },
      ...
    ],
    "FooterTotals": {
      "ClaimId": "Totals",
      "IncurredAmount": -27910474.80,
      "PaidAmount": -27910474.80
    }
  },
  "LagChart": {
    "Series": [
      {
        "Name": "Average Advice Lag",
        "Values": [
          1499,
          1048,
          897,
          2354,
          1450,
          444,
          334,
          816,
          508,
          108,
          256,
          109
        ]
      },
      {
        "Name": "Average Reserve Lag",
        "Values": [
          44,
          131,
          23,
          76,
          67,
          18,
          122,
          45,
          29,
          15,
          3,
          14
        ]
      }
    ],
    "Categories": [
      "Jan 2011",
      "Feb 2011",
      "Mar 2011",
      "Apr 2011",
      "May 2011",
      "Jun 2011",
      "Jul 2011",
      "Aug 2011",
      "Sep 2011",
      "Oct 2011",
      "Nov 2011",
      "Dec 2011"
    ]
  }
}

1 个答案:

答案 0 :(得分:2)

您可以直接在jqGrid中加载数据。要执行此操作,您只需将url参数设置为GetLagChart操作,然后稍稍更改jsonReader

jsonReader: {
    repeatitems: false,
    root: "GridData.Rows",
    page: "GridData.Page",
    total: "GridData.TotalPages",
    records: "GridData.RecordCount",
    userdata: "GridData.FooterTotals",
    id: "ClaimId"
}

loadComplete内,您可以完全访问从服务器返回的数据,因此您可以使用LagChart部分服务器响应来填充或更新图表。

The demo使用以下loadComplete

loadComplete: function (data) {
    if (typeof data.LagChart !== "undefined") {
        var chartInfo = data.LagChart
        alert ("Categories count: " + data.LagChart.Categories.length +
               "\nSeries count: " + data.LagChart.Series.length +
               "\n\nWe can fill/update the Chart");
    }
}

因此,实现中最重要的部分是提供网格数据页面的服务器方法GetResults。您可以使用filters参数扩展方法。有关更多实施详情,建议您阅读包含更多近期和扩展代码的the answerthis one