我正在使用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对于如何使用它有点薄。)
答案 0 :(得分:10)
默认情况下,在“添加”表单中使用POST
。
您可以在the old answer中找到自定义RESTfull后端的jqGrid的主要想法。
如果使用导航器工具栏的“删除”按钮,则在表单编辑中使用“删除”。查看here或here。所以你应该使用以下设置:
$("#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);
}
但我使用上面的代码可以使用方法editRow的extraparam
内的函数(请参阅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);
}
});
请注意,要从id
内postdata
获取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'(请参阅here和here)使用内联或表单编辑(或混音),您可以使用与之前描述相同的技术,但转发所有需要使用$.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/widgets
和loadonce: true
使用方法而不是属性(请参阅here和here)。
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项目数组,并且jsonReader
,page
和{{ 1}}另外。对于经典的RESTful设计,新方法可能并不奇怪,但 native 甚至SQL代码中的排序和分页数据可以极大地提高最终用户的总体性能。如果标准jqGrid输入参数(total
,records
,page
和rows
)的名称可以使用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版本。