2012-03-29 75 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

相關問題