在jqGrid中呈现之前,如何修改从AJAX调用返回的数据?

背景

我从其他开发人员那里获得了一些不完整的工作,涉及显示搜索结果。 他的方法是使用内联Javascript和jQuery将结果呈现在HTML表中,如下所示。

网格使用表和内联Javascript

我正在尝试完成工作,但我更愿意编写更少的代码并使用jqGrid,因为它包含排序function,并使代码更整洁。 让jqGrid显示结果很简单,但是将单选按钮放在空白列中比我想象的要难。

应用程序中jqGrid的版本是3.7.2。 网格需要在左侧有单选按钮以供选择,以使内容与应用程序的其余部分保持一致。

我被困在哪里

似乎没有办法在jqGrid中拥有未绑定的列。 也就是说,每列似乎都需要基础数据中的一个字段。 如果没有虚拟字段,则行数据和列标题将变为未对齐。

我遇到了一个示例 (请参阅行编辑 – >自定义编辑),它返回数据中带有虚拟字段的JSON,然后修改网格数据以插入按钮。

我的偏好是没有虚拟数据,因为它感觉很脏 :)我希望我的JSON只包含它代表搜索结果所需的数据。 所以我认为最好在脚本代码中添加虚拟字段,以便保持服务器端的代码清洁。

我试图在jqGrid渲染之前修改从AJAX调用返回的数据。 我已经尝试挂钩到loadComplete事件,但是当我修改数据时,它似乎已经在渲染之后。

我也尝试在optionsajaxGridOptions字段中挂钩success事件,但这似乎完全覆盖了事件,而jqGrid不呈现数据。

如何在jqGrid呈现之前修改从Web服务调用返回的数据?

我设法弄清楚该怎么做。 不是让jqGrid自动加载数据,而是需要手动执行请求,然后通过调用addJSONData加载它。

我的jqGrid在标记中定义如下:

 

我使用以下代码初始化网格:

 // Initialize the grid this._searchResults = this._dialog.find("#eventSearchDialog-results"); this._searchResults.jqGrid( { datatype: "local", colNames: ['', 'Event Name', 'Event Type', 'Start Date', 'End Date', 'Location', 'Event Country', 'Sports'], colModel: [ { name: 'selector', index: 'selector', width: 30 }, { name: 'EventName', index: 'EventName', formatter: jqgridCellFormatter, width: 150 }, { name: 'EventType', index: 'EventType', formatter: jqgridCellFormatter, width: 120 }, { name: 'StartDate', index: 'StartDate', formatter: jqgridCellFormatter, width: 100 }, { name: 'EndDate', index: 'EndDate', formatter: jqgridCellFormatter, width: 100 }, { name: 'Location', index: 'Location', formatter: jqgridCellFormatter, width: 100 }, { name: 'EventCountry', index: 'EventCountry', formatter: jqgridCellFormatter, width: 100 }, { name: 'Sports', index: 'Sports', formatter: jqgridCellFormatter } ], rowNum: 10, rowList: [10, 20, 30], pager: this._dialog.find("#eventSearchDialog-pager"), pginput: true, sortname: 'EventName', viewrecords: true, sortorder: "asc", hidegrid: false, height: "auto", shrinkToFit: true, width: 630, jsonReader: { page: "pageIndex", total: "pageCount", records: "recordCount", root: "rows", repeatitems: true }, prmNames: { page: "pageIndex", rows: "pageSize", sort: "sortField", order: "sortOrder" } } ); // Set the data type to JSON, we don't do this in the options because it will cause a request to occur, // but we do need it to be set to JSON so that the calls to addJSONData work later. this._searchResults.jqGrid("setGridParam", { datatype: "json" }); 

我使用来自jQuery $.ajax()调用的数据加载网格,并在success事件处理程序中填充数据,然后使用addJSONData将其加载到jqGrid中。

我的JSON看起来像这样:

 { "pageCount":1, "pageIndex":1, "recordCount":2, "rows": [ {"id":3, "cell":["Stevens Event 2", "Commonwealth Games", "03/05/2011", "16/05/2011", "sersdfweqr", "New Zealand", ["Archery"]]}, {"id":4, "cell":["Test - multiple sports", "Other", "01/05/2011", "30/06/2011", "Kobe", "Japan", ["Judo", "Karate", "Motor Sport", "Motorcycling", "Taekwondo"]]} ] } 

这是我的success处理程序:

 success: function (data, textStatus, xhr) { // Pad data for our radio button column that has no corresponding field in the data for (var counter = 0; counter < data.rows.length; counter++) { data.rows[counter].cell.splice(0, 0, null); } thisEventSearchDialog._searchResults[0].addJSONData(data); thisEventSearchDialog._createRadioButtons(); }, 

jqGrid包含需要虚拟数据的单选按钮列。 没有伪数据,行数据与标题不匹配。 在此处输入图像描述

我之前的答案中的解决方案打破了排序,所以我提出了另一个解决方案。

因为jqGrid不提供方便地修改数据的钩子,所以有必要退回一个级别并挂钩到jQuery。 我用自己的方法替换了$.ajax()方法。 首先,它检查操作是否由jqGrid启动,如果是,则填充数据,调用原始jqGrid success处理程序,然后将单选按钮添加到网格中。 排序仍然有效,数据类型仍然是json,并且没有手动调用addJSONData ,我仍然能够实现我以前的解决方案所需的。 从本质上讲,制作这个小的jQuery hack可以让我顺利完成,而不会制造任何更加混乱的jqGrid黑客。

 // Set up $.ajax() hook for modifying the data before jqGrid receives it if (!this._ajaxOverridden) { var oldAjax = $.ajax; $.ajax = function (options) { // Check whether this call is from jqGrid to our web service if (options.url == config.eventSearchUrl && options.success) { // Wrap the success event handler with our own handler that pads the data and creates the radio buttons var oldSuccess = options.success; options.success = function () { thisEventSearchDialog._padData(arguments[0]); oldSuccess.apply(this, arguments); thisEventSearchDialog._createRadioButtons(); } } oldAjax(options); }; this._ajaxOverridden = true; } 

这是一个老问题,它可能不适用于所提到的jqGrid版本(3.7.2),但它似乎与此有关: 如何在jqGrid中显示之前“预处理”ajax响应 ,如果我是对的(关于相关)然后正确的答案是dataFilter参数的dataFilter参数/函数。 它对我有用。