使用jqGrid的内联编辑与RESTful网址?

时间:2011-09-08 07:02:00

标签: ajax rest jqgrid

我正在使用jqGrid,并希望能够使用其内置的编辑功能来进行添加/编辑/删除的ajax调用。我们的API使用RESTful动词和网址,如下所示:

verb     url               action
--------------------------------------------------------------
GET      /api/widgets      get all widgets (to populate grid)
POST     /api/widgets      create new widget
PUT      /api/widgets/1    update widget 1
DELETE   /api/widgets/1    delete widget 1

是否可以使用具有这些限制的内置ajax处理,或者我是否必须使用本地数据(如here& here所示)并自行管理ajax调用?如果可能,我在网格上设置了哪些属性?

ajaxRowOptions看起来很有希望,但documentation对于如何使用它有点薄。)

3 个答案:

答案 0 :(得分:10)

默认情况下,在“添加”表单中使用POST

您可以在the old answer中找到自定义RESTfull后端的jqGrid的主要想法。

如果使用导航器工具栏的“删除”按钮,则在表单编辑中使用“删除”。查看herehere。所以你应该使用以下设置:

$("#grid").jqGrid('navGrid', '#pager',
    {edit: false, add: false, search: false}, {}, {},
    { // Delete parameters
        mtype: "DELETE",
        serializeDelData: function () {
            return ""; // don't send and body for the HTTP DELETE
        },
        onclickSubmit: function (params, postdata) {
            params.url = '/api/widgets/' + encodeURIComponent(postdata);
        }
    });

我在encodeURIComponent函数上面的示例中使用,以确保如果id将具有一些特殊字符(例如空格),则将对其进行编码,以便服务器部分自动接收原始(已解码)数据。您可能需要为在向服务器发送删除请求期间使用的$.ajax调用设置一些其他设置。您可以使用ajaxDelOptions属性。

您可以将上述设置设为默认设置。您可以通过以下方式执行此操作

$.extend($.jgrid.del, {
    mtype: "DELETE",
    serializeDelData: function () {
        return ""; // don't send and body for the HTTP DELETE
    },
    onclickSubmit: function (params, postdata) {
        params.url = '/api/widgets/' + encodeURIComponent(postdata);
    }
});

上面示例中的方法onclickSubmit可用于编辑操作(在表单编辑的情况下),以动态地将URL修改为/api/widgets/1。在许多情况下,无法使用上述形式的onclickSubmit,因为需要使用不同的基本网址('/api/widgets')不同的网格。在这种情况下,可以使用

$.extend($.jgrid.del, {
    mtype: "DELETE",
    serializeDelData: function () {
        return ""; // don't send and body for the HTTP DELETE
    },
    onclickSubmit: function (params, postdata) {
        params.url += '/' + encodeURIComponent(postdata);
    }
});

然后navGrid的使用应该明确设置为url

$("#grid").jqGrid('navGrid', '#pager',
    {edit: false, add: false, search: false}, {}, {},
    { // Delete parameters
        url: '/api/widgets'
    });

和 要在内联编辑中使用“PUT”,您可以设置以下默认的jqGrid设置:

$.extend($.jgrid.defaults, {
    ajaxRowOptions: { contentType: "application/json", type: "PUT", async: true },
    serializeRowData: function (data) {
        var propertyName, propertyValue, dataToSend = {};
        for (propertyName in data) {
            if (data.hasOwnProperty(propertyName)) {
                propertyValue = data[propertyName];
                if ($.isFunction(propertyValue)) {
                    dataToSend[propertyName] = propertyValue();
                } else {
                    dataToSend[propertyName] = propertyValue;
                }
            }
        }
        return JSON.stringify(dataToSend);
    }
});

一般不需要设置contentType: "application/json",但某些服务器技术可能需要它。上例中的回调函数serializeRowData将数据作为JSON发送。 RESTfull不需要它,但它很常见。函数JSON.stringify在最新的网络浏览器中原生实现,但为了确保它在旧浏览器中有效,您应该在页面上包含json2.js

serializeRowData的代码可能非常简单,如

serializeRowData: function (data) {
    return JSON.stringify(data);
}

但我使用上面的代码可以使用方法editRowextraparam内的函数(请参阅here和问题说明here)。

/api/widgets/1中RESTfull网址(如editRow)的使用非常简单:

$(this).editRow(rowid, true, null, null, '/api/widgets/' + encodeURIComponent(rowid));

要在表单编辑时使用它,您应该使用

grid.navGrid('#pager', {},
    { mtype: "PUT", url: '/api/widgets' });

$.extend($.jgrid.edit, {
    ajaxEditOptions: { contentType: "application/json" }, // can be not required
    onclickSubmit: function (params, postdata) {
        params.url += '/' + encodeURIComponent(postdata.list_id);
    }
});

请注意,要从idpostdata获取onclickSubmit,并且需要使用postdata.list_id代替postdata.id,其中{{1}是网格的id。为了能够使用不同的网格('list')id,可以使用 new 非标准参数。例如,在下面的代码中,我使用<table>

myGridId

,默认设置定义为

var myEditUrlBase = '/api/widgets';
grid.navGrid('#pager', {},
    { mtype: "PUT", url: myEditUrlBase, myGridId: 'list' },
    { // Add options
        url: myEditUrlBase },
    { // Delete options
        url: myEditUrlBase });

如果formatter:'actions'(请参阅herehere)使用内联或表单编辑(或混音),您可以使用与之前描述相同的技术,但转发所有需要使用$.extend($.jgrid.del, { mtype: "DELETE", serializeDelData: function () { return ""; // don't send and body for the HTTP DELETE }, onclickSubmit: function (params, postdata) { params.url += '/' + encodeURIComponent(postdata); } }); $.extend($.jgrid.edit, { ajaxEditOptions: { contentType: "application/json" }, // can be not required onclickSubmit: function (params, postdata) { params.url += '/' + encodeURIComponent(postdata[params.myGridId + '_id']); } }); editOptions格式选项的编辑/删除选项。

您的最后一个问题是使用delOptions作为GET。经典的RESTfull服务将返回所有项的数组作为/api/widgets上的响应。因此,您应该使用/api/widgetsloadonce: true使用方法而不是属性(请参阅herehere)。

jsonReader

您应该以某种方式包含哪些项属性可用作网格行ID的信息。页面上的ID必须为loadonce: true, jsonReader: { repeatitems: false, root: function (obj) { return obj; }, page: function () { return 1; }, total: function () { return 1; }, records: function (obj) { return obj.length; } } 。你的数据没有id我建议你使用

unique

作为额外的id: function () { return $.jgrid.randId(); } 方法,因为默认情况下,当前版本的jqGrid使用顺序整数(“1”,“2”,“3”,...)作为行ID。如果在同一页面上至少有两个网格,则会出现问题。

如果'GET'返回的数据大小超过100行,我建议您更好地使用服务器端分页。这意味着您将在服务器部分添加附加方法,该方法支持服务器端排序和数据分页。我建议您阅读the answer,其中我描述为什么输入数据的标准格式不是RESTfull项目数组,并且jsonReaderpage和{{ 1}}另外。对于经典的RESTful设计,新方法可能并不奇怪,但 native 甚至SQL代码中的排序和分页数据可以极大地提高最终用户的总体性能。如果标准jqGrid输入参数(totalrecordspagerows)的名称可以使用sidx jqGrid参数重命名那里。

答案 1 :(得分:1)

另外,请查看这个优秀的一般教程,了解如何为RESTful URL的here设置jqGrid,其中还包括相应的Spring MVC服务器部分的外观。

答案 2 :(得分:0)

我已经设法通过实现beforeSubmitCell事件处理程序来实现它:

beforeSubmitCell: function(rowId) {

            jQuery("#grid-HumanResource-table").jqGrid(
                'setGridParam',
                {
                    cellurl: s.getBaseModule().config.baseAPIUrl + "humanResource/" + rowId
                }
            );
        },

我使用的是jqGrid 4.6版本。