sql >> Base de Datos >  >> RDS >> Mysql

jqGrid - ID único para nueva fila

A continuación, se incluyen algunos consejos para resolver su principal problema y mejorar el código JavaScript que publicó.

En primer lugar, la generación de nuevos ID de fila localmente es necesario para el escenario de edición local. Uno debería generar los nuevos ID de fila en el servidor en caso de guardar los datos en el backend en la base de datos. La implementación típica consiste en tener PRIMARY KEY definido como int IDENTITY en cada mesa. Hace que las identificaciones sean únicas y fijas. La eliminación de alguna fila y la creación de una nueva nunca se interpretará como la edición de la fila anterior porque la nueva fila siempre obtendrá una nueva identificación, que nunca se usó antes (en la tabla).

Para aprovechar las identificaciones generadas en el lado del servidor uno tiene dos opciones principales:

  1. recargar la cuadrícula después de cada operación Agregar fila.
  2. ampliar la comunicación con el servidor en la edición para que el servidor devuelva una nueva identificación, generada en la tabla de la base de datos, a jqGrid. Uno puede usar aftersavefunc devolución de llamada (solo para Agregar nueva fila) para actualizar el ID de la fila después de crear correctamente la fila en el servidor. Muchas implementaciones estándar de servicios RESTful devuelven datos de fila completa identificación inclusiva tanto en Agregar como en Editar. Uno puede usar los datos dentro de aftersavefunc devolver la llamada y usar algo como $("#" + rowid).attr("id", newRowid); para actualizar la nueva fila. Uno guardó la identificación en algunas columnas adicionales (como si usara id oculto columna) entonces se debe usar setCell método adicional para actualizar la celda también.

La primera opción es en su mayoría simple y le recomendaría que la implemente en primer lugar. Solo si la recarga de la cuadrícula no satisface a los usuarios, que agregan muchas filas una tras otra, entonces debe escribir un poco más de código e implementar el segundo escenario.

Su código actual usa inlineNav para agregar y editar operaciones, implementadas mediante la edición en línea y el método navGrid para la operación Eliminar, implementada mediante la edición de formularios. La edición de formularios, incluida la eliminación, utiliza reloadAfterSubmit: true opción por defecto. Significa que la cuadrícula se volverá a cargar desde el servidor (desde url: "/RestWithDatabaseConnection/rest/fetchData" ) después de eliminar cada fila. Puede resolver su problema principal reemplazando afterSaveFunction a lo siguiente:

var afterSaveFunction = function () {
        $(this).trigger("reloadGrid", [{current: true, fromServer: true}]);
    };

La opción current para mantener la selección actual después de recargar y la opción fromServer: true tiene sentido solo en caso de que use loadonce: true opción adicionalmente. Simplemente puede usar reloadGridOptions: {fromServer: true} opción de navGrid para forzar la recarga de los datos desde el servidor haga clic en el botón Actualizar/Recargar de la barra del navegador. Si no tiene tantos datos que necesita mostrar en la cuadrícula (por ejemplo, menos de 1000 filas), se recomienda ese comportamiento.

Algunos consejos más comunes para mejorar su código:

Puede considerar usar height: "auto" en lugar de height: 250 y administrar la altura máxima de la cuadrícula especificando rowNum valor. La opción scrollOffset: 0 será innecesario en el caso.

El formato de los datos devueltos por el servidor parece que usted no implementó paginación, clasificación y filtrado del lado del servidor . Deberías usar loadonce: true y forceClientSorting: true opciones La loadonce: true informa a jqGrid para guardar todo los datos devueltos desde el servidor localmente en data internos parámetro. Puede acceder a la matriz en cualquier momento usando $('#grid').jqGrid("getGridParam", "data") . El valor de rowNum (el valor predeterminado es 20) se utilizará para local paginación El sortname y el sortorder se usará para local clasificación. Y usará el cuadro de diálogo de búsqueda (agregado por navGrid ) o la barra de herramientas de filtro (añadida por filterToolbar ) para local búsqueda/filtrado. Simplifica el código del servidor, mejora el rendimiento de la cuadrícula desde el punto de vista del usuario y simplifica la interfaz entre el servidor y el cliente. Puede usar la interfaz RESTful clásica en el servidor sin ninguna extensión.

Otro comentario:te recomiendo que elimines el id oculto innecesario columna (name:'id', label:'id', key: true, hidden: true, ... ). La información sobre el ID de fila se guardará en id atributo de las filas (<tr> elemento) y uno no necesita tener información duplicada en el <td> oculto elemento en cada fila.

Hay muchas otras partes de su código, que podrían mejorarse. Por ejemplo, la operación DELETE que usa en el lado del servidor parece extraña. Usas mtype: 'DELETE' , pero envía la identificación de la fila eliminada dentro de cuerpo de la solicitud al servidor en lugar de agregarla a la URL. Corresponde a los estándares, HTTP DELETE no debe contener ningún cuerpo . Puede usar la opción jqGrid formDeleting para especificar todas las opciones de eliminación y puede definir url parámetro como función:

formDeleting: {
    mtype: "DELETE",
    url: function (rowid) {
        return "/RestWithDatabaseConnection/rest/delete/" + rowid;
    },
    ajaxDelOptions: { contentType: "application/json" },
    serializeDelData: function () {
        return "";
    }
}

Debe modificar el código de su servidor de /RestWithDatabaseConnection/rest/delete/ para usar el mismo protocolo de comunicación y obtener la identificación de borrado de la URL.

Puedes usar navOptions parámetro de jqGrid gratuito para especificar las opciones de navGrid :

navOptions: { edit: false, add: false }

(searchtext: 'Search' y otras opciones que usa parecen tener valores predeterminados y los eliminé allí).

Para estar más cerca de los estándares REST, se puede usar la operación HTTP PUT para editar filas y HTTP POST para agregar nuevas filas. Debe implementar diferente puntos de entrada para ambas operaciones en el backend. Usas /RestWithDatabaseConnection/rest/update ya y puede implementar /RestWithDatabaseConnection/rest/create para agregar nuevas filas. Puede usar la siguiente inlineEditing cambios por ejemplo para implementar el escenario:

inlineNavOptions: { add: true, edit: true },
inlineEditing: {
    url: function (id, editOrAdd) {
        return "/RestWithDatabaseConnection/rest/" +
            (editOrAdd === "edit" ? "update" : "create");
    },
    mtype: function (editOrAdd) {
        return editOrAdd === "edit" ? "PUT" : "POST";
    },
    keys: true,
    serializeSaveData: function (postData) {
        return JSON.stringify(dataToSend);
    },
    aftersavefunc: function () {
        $(this).trigger("reloadGrid", [{current: true, fromServer: true}]);
    },
    addParams: {
        addRowParams: {
            position: "last",
            serializeSaveData: function (postData) {
                var dataToSend = $.extend({}, postData);
                // don't send any id in case of creating new row
                // or to send `0`:
                delete dataToSend.id; // or dataToSend.id = 0; 
                return JSON.stringify(dataToSend);
            }
        }
    }
}