【问题标题】:How do you modify the data returned from an AJAX call before it is rendered in the jqGrid?在 jqGrid 中呈现之前如何修改从 AJAX 调用返回的数据?
【发布时间】:2011-06-24 03:25:11
【问题描述】:

背景

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

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

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

我被困在哪里

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

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

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

我正在尝试在 jqGrid 呈现之前修改从 AJAX 调用返回的数据。我已经尝试连接到 loadComplete 事件,但是当我修改数据时,它似乎是在它已经呈现之后。

我还尝试在optionsajaxGridOptions 字段上挂钩success 事件,但这似乎完全覆盖了该事件并且jqGrid 不呈现数据。

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

【问题讨论】:

  • 你具体对数据做了什么?有几个选项,但这取决于你在做什么。
  • 在 jqGrid 上,我有一个空白列,我正在将控件插入其中。 trirand.com/blog/jqgrid/jqgrid.html (Row Editing -> Custom Edit) 上的示例在 JSON 响应中的单元格数组中有一个虚拟字段,但我想在 jqGrid 看到它之前将虚拟字段动态添加到客户端的响应中,而不是在从服务器端发送的响应中具有虚拟字段。
  • 在jqGrid处理数据之前没有通用的方法来修改服务器返回的数据,但是如果返回的数据是JSON格式的,你可以将数据转换成另一个在jsonReader 内部格式化或仅使用自定义格式化程序以另一种方式显示数据。您能否在问题中包含定义 jqGrid 的 JavaScript 代码和从服务器返回的完整 JSON 数据?您能否另外准确描述您想要进行哪些修改?在示例中可以找到更好的解决方案。
  • @oleg - 我正在填充数据,因为如果你不这样做,数据最终会出现在错误的列中。我在上面链接的示例使用以下代码:while($row = mysql_fetch_array($result,MYSQL_ASSOC)) { $responce->rows[$i]['id']=$row[id]; $responce->rows[$i]['cell']=array("",$row[id],$row[invdate],$row[name],$row[amount],$row[tax],$row[total],$row[note]); $i++; } 注意"" 添加为第一个字段。

标签: jquery ajax jqgrid


【解决方案1】:

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

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

<fieldset>            
    <div style="display:none" class="searchResults">
        <table id="eventSearchDialog-results">
        </table>
        <div id="eventSearchDialog-pager">
        </div>
    </div>
</fieldset>

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

// 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。没有虚拟数据,行数据与标题不匹配。

【讨论】:

  • 您没有包含jqgridCellFormatter 的代码,这对您的情况非常重要。如果您使用jsonReaderrepeatitems: true 属性,则每列的数据应该是字符串而不是数组。你想如何显示Sports 列?为什么您不对StartDateStartDate 列使用标准的date 格式化程序?我发现datatype:'local' 的使用和addJSONData 的手动调用非常糟糕的解决方法。有更好的解决方案。
  • @oleg- 因此,从我在答案中提供的图像中,您可以看到我添加的单选按钮。这就是我想要达到的目标。另一个开发人员在应用程序中有其他网格,看起来像这样,但是是用表格和 Javascript 制作的。我的任务是完成一些工作,但我更喜欢使用 jqGrid 而不是凌乱的表格和内联脚本。您建议如何使 jqGrid 看起来大致像图像但不使用 addJSONDatadatatype:'local'
【解决方案2】:

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

因为 jqGrid 没有提供方便修改数据的钩子,所以需要回退一个关卡并钩入 jQuery。我用自己的方法替换了$.ajax() 方法。首先,它检查该操作是否是由 jqGrid 发起的,如果是,则填充数据,调用原始 jqGrid success 处理程序,然后将单选按钮添加到网格中。排序仍然有效,数据类型仍然是 json,并且没有手动调用 addJSONData 并且我仍然能够从以前的解决方案中实现我所需要的。从本质上讲,制作这个小的 jQuery hack 可以让我在不做任何麻烦得多的 jqGrid hack 的情况下度过难关。

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

【讨论】:

    【解决方案3】:

    这是一个老问题,它可能不适用于提到的jqGrid版本(3.7.2),但它似乎与此有关:How to "pre-process" an ajax response before displaying in jqGrid如果我是对的(关于相关) 那么正确答案是dataFilter 参数/ajaxGridOption 参数的函数。它对我有用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-04-07
      • 2014-03-05
      • 1970-01-01
      • 1970-01-01
      • 2012-10-29
      • 2021-09-11
      • 1970-01-01
      相关资源
      最近更新 更多