¿Utiliza la edición en línea de jqGrid con URLs RESTful?

Estoy usando jqGrid y me gustaría poder usar sus funciones de edición integradas para hacer llamadas ajax para agregar / editar / eliminar. Nuestra API usa verbos RESTful y URL como esta:

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 

¿Es posible utilizar el manejo integrado de ajax con estas restricciones, o tengo que usar datos locales (como se describe aquí y aquí ) y administrar las llamadas ajax a mí mismo? Si es posible, ¿qué propiedades configuro en la grilla?

( ajaxRowOptions parece prometedor, pero la documentación es un poco escasa sobre cómo usarlo).

El uso de POST en Agregar forma es por defecto.

La idea principal para personalizar jqGrid para RESTfull back-end puede encontrarla en la respuesta anterior .

Para usar ‘DELETE’ en la edición de formularios, use el botón Eliminar de la barra de herramientas del navegador. Mira aquí o aquí . Por lo tanto, debe usar las siguientes configuraciones:

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

Utilizo en el ejemplo anterior la función encodeURIComponent para asegurarme de que si el ID tiene algunos caracteres especiales (espacios por ejemplo) si se codificará para que la parte del servidor reciba automáticamente los datos originales (decodificados). Probablemente necesite establecer algunas configuraciones adicionales para la llamada $.ajax utilizada durante el envío de la solicitud de eliminación al servidor. Puede usar la propiedad ajaxDelOptions .

Puede hacer que la configuración anterior sea su configuración predeterminada . Puedes hacer esto con respecto a lo siguiente

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

El método onclickSubmit del ejemplo anterior se puede usar para las operaciones de Edición (en el caso de la edición de formularios) para modificar la URL dinámicamente a /api/widgets/1 . En muchos casos, el uso de onclickSubmit en el formulario anterior no es posible porque hay que usar diferentes redes base ( '/api/widgets' ) diferentes grillas. En el caso, uno puede usar

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

Entonces, el uso de navGrid debe ser con configuración explícita de url

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

y Para usar ‘PUT’ en la edición en línea, puede establecer la siguiente configuración jqGrid predeterminada:

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

La configuración contentType: "application/json" no es obligatoria en general, pero podría ser necesaria para algunas tecnologías de servidor. La función de callback serializeRowData del ejemplo anterior envió los datos como JSON. No es necesario para RESTfull, pero es muy común. La función JSON.stringify se implementa de forma nativa en los navegadores web más recientes, pero para asegurarse de que funciona en navegadores antiguos, debe incluir json2.js en su página.

El código de serializeRowData podría ser muy simple como

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

pero utilizo el código anterior para poder usar funciones dentro del extraparam del método editRow (vea aquí y la descripción del problema aquí ).

El uso de la URL RESTfull (como /api/widgets/1 ) en editRow es muy simple:

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

Para usarlo en el caso de la edición del formulario, debes usar

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

y

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

Es importante destacar que para obtener una id de los postdata dentro de onclickSubmit y necesita usar postdata.list_id lugar de postdata.id , donde 'list' es la identificación de la grilla. Para poder usar diferentes identificadores de cuadrícula (

) uno puede usar un nuevo parámetro no estándar. Por ejemplo, en el siguiente código, uso myGridId :

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

y la configuración predeterminada definida como

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

En el caso del uso del formateador: ‘acciones’ (ver aquí y aquí ) con edición en línea o en forma (o una mezcla) puede usar la misma técnica que se describió anteriormente, pero reenviar todas las opciones necesarias Editar / Eliminar usando editOptions y delOptions formatoptions .

La última pregunta fue sobre el uso de GET como /api/widgets . Los servicios RESTfull clásicos devolverán solo una matriz de todos los elementos como la respuesta en /api/widgets . Entonces debería usar loadonce: true y jsonReader que usaron métodos en lugar de propiedades (Vea aquí y aquí ).

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

De alguna manera, debe incluir información sobre la propiedad del elemento que se puede usar como ID de las filas de la grilla. La identificación debe ser unique en la página. Si sus datos no tienen una identificación, le recomendaría que use

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

como un método adicional de jsonReader porque por defecto la versión actual de jqGrid usa enteros secuenciales (“1”, “2”, “3”, …) como los identificadores de fila. En caso de tener al menos dos cuadrículas en la misma página, seguirá los problemas.

Si el tamaño de los datos devueltos por ‘OBTENER’ son más de 100 filas, recomendaría mejor utilizar la paginación del lado del servidor. Significa que agregará un método adicional en la parte del servidor que admite la clasificación y paginación de datos del lado del servidor. Te recomiendo que leas la respuesta donde describí por qué el formato estándar de los datos de entrada no es una matriz REST llena de elementos y tiene una page , un total y records adicionales. El nuevo método probablemente no sea extraño para el diseño RESTful clásico, pero los datos de ordenación y paginación en código nativo o incluso SQL pueden mejorar el rendimiento total desde el lado del usuario final de forma espectacular. Si los nombres de los parámetros de entrada jqGrid estándar ( page , rows , sidx y sidx ) puede usar el parámetro prmNames jqGrid para cambiar el nombre allí.

También consulte este excelente tutorial general sobre cómo configurar jqGrid para URL RESTful aquí , que también incluye cómo se vería la porción correspondiente del servidor Spring MVC.

Logré lograrlo implementando el controlador de eventos beforeSubmitCell:

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

Estoy usando la versión jqGrid 4.6.