2012-03-29 3 views
0

Я использую jqGrid (4.3.1) в веб-приложении ASP.NET MVC 3.jqGrid Использование JsonString-JsonReader Реализация серверной сортировки Пейджинговая фильтрация

У меня есть уникальная ситуация (по крайней мере, одна, на которую я не могу найти решение), поскольку мне предоставляются мои данные из внешнего источника - в разбитых на фрагменты фрагменты - поэтому я не могу использовать свойство url для сетка, но я все же должен выполнить сортировку на стороне сервера, пейджинг, фильтрацию &.

Мой план (после того, как я разрешил ниже) использовать методы onPaging, onSortCol и beginSearch для возврата к веб-службе и обновления данных сетки в обратном вызове.

Данные поставляются в формате расходного по jqGrid (я могу легко сопоставить его с помощью опции jsonReader):

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

я передать данные с помощью опции datastr и установить тип данных к «jsonstring» ,

loadonce устанавливается в ложь (я пробовал оба способа), и мой RowNum установлен на 10.

Когда я делаю первоначальный вызов набора данных с ~ 900 записей возвращается, а сетка отображает первые 10 записей, , но пейджер игнорирует 'total' & 'records' и думает, что у меня есть только 1 страница данных.

Корневые данные не игнорируются (он отображает 10 записей), и пользовательские данные не игнорируются (т. Е. Нижний колонтитул правильно отображает). поэтому сетка выборочно игнорирует данные «total» и «records» из datastr.

Мой вопрос - использует ли тип данных: 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 (подробнее Олега):

Аякса вызовов в контроллер метод (который имеет комментарии, которые ссылаются на классы, описанные ниже его).Этот метод придерживается 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; } 
} 

Sample сообщение Json к веб-службы (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? Каков интерфейс веб-сервиса? Поскольку вы писали о веб-приложении ASP.NET MVC 3, я все меньше понимаю. jqGrid позволяет очень гибко. Поэтому, если вы включите дополнительную информацию об интерфейсе в веб-службу или разместите код, который вы используете в настоящее время для его вызова, я попытаюсь показать вам, как интегрировать вызов в jqGrid. – Oleg

+0

@ Oleg - Спасибо за быстрый ответ. Исходный вызов веб-службы возвращает данные сетки вместе со многими другими элементами данных, относящимися к остальной части страницы в модели представления. Если я использую URL-адрес, у меня нет доступа к этим данным. По крайней мере, я не знаю. jqGrid - это одна часть более крупной страницы, в которой первые 10 записей заполнены. Вот почему я надеялся, что могу передать json (который передается мне через отдельный вызов ajax) в сетку с использованием datastr/jsonstring, а затем вызвать веб-службу (опять же, что я не контролирую) для пейджинга/фильтрации/сортировка данных. – kmk

+0

Вы можете получить полный доступ к ответу сервера, вы можете даже изменить его, если необходимо, прежде чем он будет обработан jqGrid. Вы также можете заполнить или обновить внешние поля после получения данных с сервера. Если вы просто описываете поле внешних данных, отправьте вызов Ajax, который вы используете для получения данных с сервера, и включите пример ответа JSON (достаточно данных одной сетки и одного внешнего поля). Я мог бы показать, как вы можете сделай это. – Oleg

ответ

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 answer или this one, который содержит более свежий и расширенный код.

+0

спасибо. Я буду разбирать то, что мне нужно от объекта данных в loadComplete, как вы предлагаете. – kmk

+0

@kmk: Добро пожаловать! Не забудьте также установить 'gridview' в' true'.Сетка будет работать быстро без недостатков. Можно увидеть преимущества производительности только со многими рядами данных. – Oleg

+0

Я отправил вам электронное письмо по приведенным выше данным. Пожалуйста, взгляните, когда у вас появится шанс (не связанный с SO). Спасибо за вашу помощь. – kmk

Смежные вопросы