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

时间:2022-07-23 14:30:34

I'm using jqGrid and would like to be able to use its built-in editing functions to make ajax calls to add/edit/delete. Our API uses RESTful verbs and urls like so:

我正在使用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

Is it possible to use the built-in ajax handling with these restrictions, or do I have to use local data (as outlined here & here) and manage the ajax calls myself? If it is possible, what properties do I set on the grid?

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

(ajaxRowOptions looks promising, but the documentation is a bit thin on how to use it.)

(ajaxRowOptions看起来很有前途,但文档在如何使用它方面有点薄。)

3 个解决方案

#1


10  

The usage of POST in Add form is by default.

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

The main idea for customizing jqGrid for RESTfull backend you can find in the old answer.

您可以在旧答案中找到为RESTfull后端自定义jqGrid的主要想法。

To use 'DELETE' in form editing if you use the Delete button of the navigator toolbar. Look at here or here. So you should use about the following settings:

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

$("#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);
        }
    });

I use in the example above the encodeURIComponent function to be sure that if the id will have some special characters (spaces for example) if will be encoded so that the server part automatically received the original (decoded) data. Probably you will need to set some additional settings for the $.ajax call used during sending Delete request to the server. You can use for it ajaxDelOptions property.

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

You can make the above settings as your default settings. You can do this with respect of the following

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

$.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);
    }
});

The method onclickSubmit from the example above can be used for the Edit operations (in case of form editing) to modify the URL dynamically to /api/widgets/1. In many cases the usage of onclickSubmit in the above form is not possible because one need to use different base urls ('/api/widgets') different grids. In the case one can use

上面示例中的onclickSubmit方法可用于编辑操作(在表单编辑的情况下)将URL动态修改为/ api / widgets / 1。在许多情况下,无法使用上述形式的onclickSubmit,因为需要使用不同的基本URL('/ 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);
    }
});

Then the usage of navGrid should be with explicit setting of url

然后navGrid的用法应该是显式的url设置

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

and To use 'PUT' in inline editing you can set the following default jqGrid settings:

要在内联编辑中使用“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);
    }
});

The setting contentType: "application/json" is not required in general, but it could be required for some server technologies. The callback function serializeRowData from the example above sent the data as JSON. It is not required for RESTfull, but it's very common. The function JSON.stringify is native implemented in the most recent web browsers, but to be sure that it work in old browsers to you should include json2.js on your page.

设置contentType:“application / json”通常不是必需的,但某些服务器技术可能需要它。上例中的回调函数serializeRowData将数据作为JSON发送。 RESTfull不需要它,但它很常见。函数JSON.stringify是在最新的Web浏览器中本机实现的,但为了确保它在旧浏览器中工作,您应该在页面上包含json2.js。

The code of serializeRowData could be very simple like

serializeRowData的代码可以非常简单

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

but I use above code to be able to use functions inside of the extraparam of the method editRow (see here and the problem description here).

但我使用上面的代码能够使用方法editRow的extraparam内部的函数(请参阅此处和此处的问题描述)。

The usage of the RESTfull URL (like /api/widgets/1) in the editRow is very simple:

在editRow中使用RESTfull URL(如/ api / widgets / 1)非常简单:

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

To use it in case of the form editing you should use

要在表单编辑的情况下使用它,您应该使用它

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

and

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

It is important to remark that to get id from the postdata inside of onclickSubmit and need use postdata.list_id instead of postdata.id, where 'list' is the id of the grid. To be able to use different grid (<table>) ids one can use new non-standard parameter. For example, in the code below I use myGridId:

重要的是要注意从onclickSubmit中的postdata获取id并且需要使用postdata.list_id而不是postdata.id,其中'list'是网格的id。为了能够使用不同的网格(

)id,可以使用新的非标准参数。例如,在下面的代码中我使用myGridId:
var myEditUrlBase = '/api/widgets';
grid.navGrid('#pager', {},
    { mtype: "PUT", url: myEditUrlBase, myGridId: 'list' },
    { // Add options
        url: myEditUrlBase },
    { // Delete options
        url: myEditUrlBase });

and the default setting defined as

和默认设置定义为

$.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']);
    }
});

In case of the usage of formatter:'actions' (see here and here) with inline or form editing (or a mix) you can use the same technique as described before, but forward all needed Edit/Delete option using editOptions and delOptions formatoptions.

如果使用格式化程序:'actions'(请参阅此处和此处)使用内联或表单编辑(或混合),您可以使用与前面描述相同的技术,但使用editOptions和delOptions formatoptions转发所有需要的编辑/删除选项。

The last your question was the usage of GET as /api/widgets. The classical RESTfull services will returns just array of all items as the response on /api/widgets. So you should just use loadonce: true and jsonReader which used methods instead of properties (See here and here).

最后一个问题是使用GET作为/ api / widgets。经典的RESTfull服务将返回所有项的数组作为/ api / widgets上的响应。所以你应该只使用loadonce:true和jsonReader,它使用方法而不是属性(参见这里和这里)。

loadonce: true,
jsonReader: {
    repeatitems: false,
    root: function (obj) { return obj; },
    page: function () { return 1; },
    total: function () { return 1; },
    records: function (obj) { return obj.length; }
}

You should in some way include information which item property can be used as the id of grid rows. The id must be unique on the page. It your data has no id I would recommend you to use

您应该以某种方式包含哪些项属性可以用作网格行的ID的信息。 id必须在页面上是唯一的。你的数据没有我建议你使用的id

id: function () { return $.jgrid.randId(); }

as an additional jsonReader method because per default the current version of jqGrid use sequential integers ("1", "2", "3", ...) as the row ids. In case of having at least two grids on the same page it will follow to the problems.

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

If the size of the data returned by 'GET' are more as 100 rows I would you recommend better to use server side paging. It means that you will add an additional method in the server part which support server side sorting and paging of data. I recommend you to read the answer where I described why the standard format of the input data are not RESTfull array of items and has page, total and records additionally. The new method will be probably not strange for the classical RESTful design, but the sorting and paging data in native or even SQL code can improve the total performance from the side of enduser dramatically. If the names of the standard jqGrid input parameters (page, rows, sidx and sord) you can use prmNames jqGrid parameter to rename there.

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

#2


1  

Also check out this excellent general tutorial for how to set-up jqGrid for RESTful URL's here, which also includes how the corresponding Spring MVC server portion would look.

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

#3


0  

I have managed to achieve it by implementing beforeSubmitCell event handler:

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

beforeSubmitCell: function(rowId) {

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

I am using jqGrid 4.6 version.

我使用的是jqGrid 4.6版本。

#1


10  

The usage of POST in Add form is by default.

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

The main idea for customizing jqGrid for RESTfull backend you can find in the old answer.

您可以在旧答案中找到为RESTfull后端自定义jqGrid的主要想法。

To use 'DELETE' in form editing if you use the Delete button of the navigator toolbar. Look at here or here. So you should use about the following settings:

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

$("#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);
        }
    });

I use in the example above the encodeURIComponent function to be sure that if the id will have some special characters (spaces for example) if will be encoded so that the server part automatically received the original (decoded) data. Probably you will need to set some additional settings for the $.ajax call used during sending Delete request to the server. You can use for it ajaxDelOptions property.

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

You can make the above settings as your default settings. You can do this with respect of the following

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

$.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);
    }
});

The method onclickSubmit from the example above can be used for the Edit operations (in case of form editing) to modify the URL dynamically to /api/widgets/1. In many cases the usage of onclickSubmit in the above form is not possible because one need to use different base urls ('/api/widgets') different grids. In the case one can use

上面示例中的onclickSubmit方法可用于编辑操作(在表单编辑的情况下)将URL动态修改为/ api / widgets / 1。在许多情况下,无法使用上述形式的onclickSubmit,因为需要使用不同的基本URL('/ 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);
    }
});

Then the usage of navGrid should be with explicit setting of url

然后navGrid的用法应该是显式的url设置

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

and To use 'PUT' in inline editing you can set the following default jqGrid settings:

要在内联编辑中使用“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);
    }
});

The setting contentType: "application/json" is not required in general, but it could be required for some server technologies. The callback function serializeRowData from the example above sent the data as JSON. It is not required for RESTfull, but it's very common. The function JSON.stringify is native implemented in the most recent web browsers, but to be sure that it work in old browsers to you should include json2.js on your page.

设置contentType:“application / json”通常不是必需的,但某些服务器技术可能需要它。上例中的回调函数serializeRowData将数据作为JSON发送。 RESTfull不需要它,但它很常见。函数JSON.stringify是在最新的Web浏览器中本机实现的,但为了确保它在旧浏览器中工作,您应该在页面上包含json2.js。

The code of serializeRowData could be very simple like

serializeRowData的代码可以非常简单

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

but I use above code to be able to use functions inside of the extraparam of the method editRow (see here and the problem description here).

但我使用上面的代码能够使用方法editRow的extraparam内部的函数(请参阅此处和此处的问题描述)。

The usage of the RESTfull URL (like /api/widgets/1) in the editRow is very simple:

在editRow中使用RESTfull URL(如/ api / widgets / 1)非常简单:

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

To use it in case of the form editing you should use

要在表单编辑的情况下使用它,您应该使用它

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

and

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

It is important to remark that to get id from the postdata inside of onclickSubmit and need use postdata.list_id instead of postdata.id, where 'list' is the id of the grid. To be able to use different grid (<table>) ids one can use new non-standard parameter. For example, in the code below I use myGridId:

重要的是要注意从onclickSubmit中的postdata获取id并且需要使用postdata.list_id而不是postdata.id,其中'list'是网格的id。为了能够使用不同的网格(

)id,可以使用新的非标准参数。例如,在下面的代码中我使用myGridId:
var myEditUrlBase = '/api/widgets';
grid.navGrid('#pager', {},
    { mtype: "PUT", url: myEditUrlBase, myGridId: 'list' },
    { // Add options
        url: myEditUrlBase },
    { // Delete options
        url: myEditUrlBase });

and the default setting defined as

和默认设置定义为

$.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']);
    }
});

In case of the usage of formatter:'actions' (see here and here) with inline or form editing (or a mix) you can use the same technique as described before, but forward all needed Edit/Delete option using editOptions and delOptions formatoptions.

如果使用格式化程序:'actions'(请参阅此处和此处)使用内联或表单编辑(或混合),您可以使用与前面描述相同的技术,但使用editOptions和delOptions formatoptions转发所有需要的编辑/删除选项。

The last your question was the usage of GET as /api/widgets. The classical RESTfull services will returns just array of all items as the response on /api/widgets. So you should just use loadonce: true and jsonReader which used methods instead of properties (See here and here).

最后一个问题是使用GET作为/ api / widgets。经典的RESTfull服务将返回所有项的数组作为/ api / widgets上的响应。所以你应该只使用loadonce:true和jsonReader,它使用方法而不是属性(参见这里和这里)。

loadonce: true,
jsonReader: {
    repeatitems: false,
    root: function (obj) { return obj; },
    page: function () { return 1; },
    total: function () { return 1; },
    records: function (obj) { return obj.length; }
}

You should in some way include information which item property can be used as the id of grid rows. The id must be unique on the page. It your data has no id I would recommend you to use

您应该以某种方式包含哪些项属性可以用作网格行的ID的信息。 id必须在页面上是唯一的。你的数据没有我建议你使用的id

id: function () { return $.jgrid.randId(); }

as an additional jsonReader method because per default the current version of jqGrid use sequential integers ("1", "2", "3", ...) as the row ids. In case of having at least two grids on the same page it will follow to the problems.

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

If the size of the data returned by 'GET' are more as 100 rows I would you recommend better to use server side paging. It means that you will add an additional method in the server part which support server side sorting and paging of data. I recommend you to read the answer where I described why the standard format of the input data are not RESTfull array of items and has page, total and records additionally. The new method will be probably not strange for the classical RESTful design, but the sorting and paging data in native or even SQL code can improve the total performance from the side of enduser dramatically. If the names of the standard jqGrid input parameters (page, rows, sidx and sord) you can use prmNames jqGrid parameter to rename there.

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

#2


1  

Also check out this excellent general tutorial for how to set-up jqGrid for RESTful URL's here, which also includes how the corresponding Spring MVC server portion would look.

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

#3


0  

I have managed to achieve it by implementing beforeSubmitCell event handler:

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

beforeSubmitCell: function(rowId) {

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

I am using jqGrid 4.6 version.

我使用的是jqGrid 4.6版本。