2012-03-29 76 views
0

我在ASP.NET MVC 3 Web应用程序中使用jqGrid(4.3.1)。jqGrid使用JsonString-JsonReader实现服务器端排序分页过滤

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

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

数据在通过的jqGrid格式消耗品供应(I可以在经由jsonReader选项容易映射):

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

我经由datastr选项传入数据和设置数据类型为“jsonstring” 。

loadonce设置为false(我已经试过这两种方法),当我做最初的电话与〜900所记录的数据集回来我的rowNum设置为10

,并在网格显示前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 }); 
}; 

UPDATE(为奥列格的详细信息):

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); 
    } 

在上面的代码中提到的图表类:上述

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 - 控制器):

{“page”:1,“rows”:10,“sidx”:“ClaimId”,“sord”:“asc”,“_ search”:false,“filters”:null,“quick”:“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" 
    ] 
    } 
} 
+0

我不明白你为什么不能直接从“外部源”加载数据。你写道你称之为“网络服务”。你做单独的Ajax调用吗?你使用JSON还是JSONP调用?什么是Web服务的界面?因为你写了关于ASP.NET MVC 3的Web应用程序,所以我理解了所有事件。 jqGrid允许非常灵活。因此,如果您包含有关Web服务接口的更多详细信息或发布您当前使用的代码来调用它,我会尝试向您展示如何将调用集成到jqGrid中。 – Oleg 2012-03-29 19:21:36

+0

@Oleg - 感谢您的快速响应。原始的Web服务调用将视图模型中的网格数据以及与页面其余部分相关的许多其他数据元素带回。如果我使用网址,我无法访问这些数据。至少我没有办法知道。 jqGrid是一个更大的页面,前10个记录被填充。这就是为什么我希望我可以使用datastr/jsonstring将json(通过单独的ajax调用交给我)传递给网格,然后调用Web服务(再次,我不控制)进行分页/过滤/排序数据。 – kmk 2012-03-29 20:05:38

+0

您可以完全访问服务器响应,您甚至可以在需要之前对其进行修改,然后再由jqGrid进行处理。从服务器获取数据后,您还可以填写或刷新外部字段。如果您只是描述外部数据的字段,请发布Ajax调用,您可以使用它从服务器获取数据,并包含JSON响应的示例(一行网格数据和一个外部字段就足够了)我可以展示如何做这个。 – Oleg 2012-03-29 20:13:20

回答

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,其中包含更新的代码和扩展代码。

+0

谢谢。我将根据你的建议,从loadComplete中的数据对象中解析出我需要的东西。 – kmk 2012-03-30 13:41:17

+0

@kmk:不客气!不要忘了将'gridview'设置为'true'。电网将会很快运行,没有缺点。只有多行数据才能真正看到性能优势。 – Oleg 2012-03-30 13:43:27

+0

我向您发送了一封有关上述数据的电子邮件。当你有机会时请看看(与SO无关)。谢谢你的帮助。 – kmk 2012-03-30 13:54:47

相关问题