2012-03-29 4 views
0

Ich verwende jqGrid (4.3.1) in einer ASP.NET MVC 3-Webanwendung.jqGrid Verwenden von JsonString-JsonReader Implementieren der serverseitigen Filterung der Sortierpagingfunktion

Ich habe eine einzigartige Situation (zumindest eine, für die ich keine Lösung finden kann) in dem ich meine Daten von einer externen Quelle - in ausgelagerten Fragmenten geliefert werden - so kann ich nicht die URL-Eigenschaft des verwenden Grid, aber ich muss noch Server-Side-Sortierung, Paging, & Filterung implementieren.

Mein Plan ist (sobald ich das unten lösen), die Methoden onPaging, onSortCol und beginSearch zu verwenden, um zurück zum Webdienst aufzurufen und die Rasterdaten im Callback zu aktualisieren.

Die Daten werden in einem Format Verbrauch von jqGrid geliefert (ich es über die jsonReader Option leicht zuordnen kann):

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

ich in den Daten über die datastr Option übergeben und stellen Sie den Datentyp ‚jsonstring‘ .

loadonce auf false gesetzt ist (ich habe es in beide Richtungen ausprobiert) und meine rowNum ist auf 10.

Als ich den ersten Anruf ein Datensatz mit ~ 900 Aufzeichnungen machen zurückkommt, und das Raster zeigt die erste 10 Datensätze, , aber der Pager ignoriert die "Gesamt" & "Datensätze" und denkt, ich habe nur 1 Seite der Daten.

Die Stammdaten werden nicht ignoriert (es werden 10 Datensätze angezeigt) und die Benutzerdaten werden nicht ignoriert (d. H. Die Fußzeile wird korrekt gerendert). Das Raster ignoriert also selektiv die Daten "total" und "records" vom Datastr.

Meine Frage ist - tut mit Datentyp: jsonstring und datastr (und die Bereitstellung json zum Grid anstelle der Verwendung der URL) verbieten die Möglichkeit, Server Seite Paging/Sortieren/Filtern zu nutzen?

Wenn ja, gibt es eine Möglichkeit, das zu erreichen, wonach ich suche?

beachten Sie, dass, wenn ich die gesamte 900-Count-Record-Set zurückgeben und loadonce auf True setzen, alles funktioniert, wenn auch Client-Seite.

meine ganze jqGrid, als Referenz:

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 (weitere Informationen für Oleg):

Die Ajax in eine Controller-Methode aufruft (die Kommentare, die die Klassen unten beschrieben Referenz hat).Dieses Verfahren hält sich an die jqGrid JSON-serialisiert postdata Struktur (mit einigen zusätzlichen Parameter):

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

Das Diagramm Klasse im Code oben erwähnt:

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

die jqGrid Griddata Klasse oben erwähnt:

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

Probe Beitrag Json auf dem Web-Service (Httppost-fähigen Controller):

{"page": 1, "Zeilen": 10, "sidx": "ClaimId", "sord": "asc", "_ search": false, "Filter": null, "quick": "exc"}

Antwort 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

Ich verstehe nicht, warum Sie die Daten nicht direkt von der "externen Quelle" laden können. Du hast geschrieben, dass du "den Webservice" nennst. Machst du einen separaten Ajax-Anruf? Verwenden Sie einen JSON- oder JSONP-Aufruf? Was ist die Schnittstelle des Web Service? Weil Sie über ASP.NET MVC 3 Webanwendung geschrieben haben, verstehe ich alle Ereignisse weniger. jqGrid ermöglicht sehr viel Flexibilität. Wenn Sie also mehr Details über die Schnittstelle zum Web-Service angeben oder den Code posten, mit dem Sie ihn derzeit aufrufen, würde ich versuchen, Ihnen zu zeigen, wie Sie den Aufruf in jqGrid integrieren. – Oleg

+0

@Oleg - Danke für die schnelle Antwort. Der ursprüngliche Web-Service-Aufruf bringt die Rasterdaten zusammen mit vielen anderen für den Rest der Seite relevanten Datenelementen in einem Ansichtsmodell zurück. Wenn ich die URL verwende, habe ich keine Möglichkeit, auf diese Daten zuzugreifen. Zumindest nicht, dass ich davon weiß. Das jqGrid ist ein Teil einer größeren Seite, wobei die ersten 10 Datensätze im Vordergrund stehen. Deshalb habe ich gehofft, dass ich den JSON (der mir über einen separaten Ajax-Aufruf übergeben wird) mit datastr/jsonstring an das Grid weiterleiten und dann den Web-Service (wiederum den ich nicht kontrolliere) für Paging/Filtering anrufen kann/Sortieren der Daten – kmk

+0

Sie können vollständigen Zugriff auf die Serverantwort erhalten, Sie können sie sogar ändern, bevor sie von jqGrid verarbeitet wird. Sie können die externen Felder auch füllen oder aktualisieren, nachdem Sie die Daten vom Server erhalten haben. Wenn Sie nur das Feld der externen Daten beschreiben, geben Sie den Ajax-Aufruf ein, den Sie zum Abrufen von Daten vom Server verwenden, und fügen Sie das Beispiel der JSON-Antwort ein (ein Zeilengitter und ein externes Feld wären ausreichend) mach das. – Oleg

Antwort

2

Sie können die Daten direkt in jqGrid laden. Dazu benötigen Sie setzen nur url Parameter an die GetLagChart Aktion und ändern Sie die jsonReader ein wenig:

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

Innerhalb von loadComplete Sie vollen Zugriff auf die Daten von dem Server zurückgegeben und so können Sie LagChart Teil des verwendungs Serverantwort zum Füllen oder Aktualisieren des Diagramms.

The demo verwendet zu folgenden 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"); 
    } 
} 

So ist der wichtigste Teil Ihrer Implementierung die Server-Methode GetResults sein, die die Seite von Rasterdaten zur Verfügung stellen. Sie können die Methode um den Parameter filters erweitern. Für weitere Implementierungsdetails empfehle ich Ihnen, the answer oder this one zu lesen, das neueren und erweiterten Code enthält.

+0

danke. Ich werde analysieren, was ich brauche, aus dem Datenobjekt in loadComplete, wie Sie vorschlagen. – kmk

+0

@kmk: Gern geschehen! Vergessen Sie nicht, 'gridview' auch auf' true' zu ​​setzen.Das Raster wird nur schnell ohne Nachteile funktionieren. Man kann die Leistungsvorteile nur bei vielen Datenzeilen sehen. – Oleg

+0

Ich habe Ihnen eine E-Mail zu den oben genannten Daten gesendet. Bitte schauen Sie, wenn Sie eine Chance bekommen (unabhängig von SO). Danke für Ihre Hilfe. – kmk

Verwandte Themen