Mysql
 sql >> Database >  >> RDS >> Mysql

jqGrid - ID univoco per la nuova riga

Di seguito sono riportati alcuni consigli per risolvere il tuo problema principale e per migliorare il codice JavaScript che hai pubblicato.

Prima di tutto, la generazione di nuovi rowid a livello locale è richiesto per lo scenario di modifica locale. Si dovrebbero generare i nuovi rowid sul server in caso di salvataggio dei dati sul backend nel database. Un'implementazione tipica consiste nell'avere PRIMARY KEY definito come int IDENTITY in ogni tavolo. Rende gli ID unici e fissi. L'eliminazione di una riga e la creazione di quella nuova non verranno mai interpretate come modifica della vecchia riga perché la nuova riga avrà sempre un nuovo ID, che non è mai stato utilizzato prima (nella tabella).

Per sfruttare gli ID generati sul lato server uno ha due scelte principali:

  1. ricaricare la griglia dopo ogni operazione di aggiunta riga.
  2. estendendo la comunicazione con il server durante la modifica in modo che il server restituisca il nuovo id, generato nella tabella del database, a jqGrid. Si può usare aftersavefunc callback (solo per Aggiungi nuova riga) per aggiornare l'ID riga dopo aver creato correttamente la riga sul server. Molte implementazioni standard dei servizi RESTful restituiscono dati di riga completa ID inclusivo sia su Aggiungi che su Modifica. È possibile utilizzare i dati all'interno di aftersavefunc richiama e usa qualcosa come $("#" + rowid).attr("id", newRowid); per aggiornare la nuova riga. Ha salvato l'id in alcune colonne aggiuntive (come se usi id nascosto colonna) allora si dovrebbe usare setCell metodo in aggiunta per aggiornare anche la cella.

La prima scelta è per lo più semplice e ti consiglierei di implementarla prima di tutto. Solo se il ricaricamento della griglia non soddisfa gli utenti, che aggiungono tante righe una dopo l'altra, allora dovresti scrivere un po' più di codice e implementare il secondo scenario.

Il tuo codice attuale usa inlineNav per le operazioni di aggiunta e modifica, implementate utilizzando la modifica in linea, e il metodo navGrid per l'operazione di eliminazione, implementata utilizzando la modifica del modulo. La modifica del modulo, inclusa Elimina, utilizza reloadAfterSubmit: true opzione per impostazione predefinita. Significa che la griglia verrà ricaricata dal server (da url: "/RestWithDatabaseConnection/rest/fetchData" ) dopo aver eliminato ogni riga. Puoi risolvere il tuo problema principale sostituendo afterSaveFunction al seguente:

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

L'opzione current per mantenere la selezione corrente dopo il ricaricamento e l'opzione fromServer: true ha senso solo nel caso in cui usi loadonce: true opzione in aggiunta. Puoi semplicemente usare reloadGridOptions: {fromServer: true} opzione di navGrid per forzare il ricaricamento dei dati dal server quindi fare clic sul pulsante Aggiorna/Ricarica della barra del navigatore. Se non hai molti dati da visualizzare nella griglia (ad esempio meno di 1000 righe), allora questo comportamento sarebbe consigliato.

Alcuni consigli più comuni per te per migliorare il tuo codice:

Puoi considerare di utilizzare height: "auto" invece di height: 250 e per gestire l'altezza massima della griglia specificando rowNum valore. L'opzione scrollOffset: 0 non sarà necessario nel caso.

Il formato dei dati restituiti dal server sembra tale da non implementare il paging, l'ordinamento e il filtraggio lato server . Dovresti usare loadonce: true e forceClientSorting: true opzioni. Il loadonce: true informa jqGrid di salvare tutto i dati restituiti dal server localmente nei data interni parametro. Puoi accedere all'array in qualsiasi momento utilizzando $('#grid').jqGrid("getGridParam", "data") . Il valore di rowNum (il valore predefinito è 20) verrà utilizzato per locale impaginazione. Il sortname e il sortorder verrà utilizzato per locale ordinamento. E utilizzerai la finestra di ricerca (aggiunto da navGrid ) o la barra degli strumenti del filtro (aggiunto da filterToolbar ) per locale ricerca/filtraggio. Semplifica il codice del server, migliora le prestazioni della griglia dal punto di vista dell'utente e semplifica l'interfaccia tra il server e il client. Puoi utilizzare la classica interfaccia RESTful sul server senza alcuna estensione.

Un'altra osservazione:ti consiglio di rimuovere gli id nascosti non necessari colonna (name:'id', label:'id', key: true, hidden: true, ... ). Le informazioni sul rowid verranno salvate in id attributo delle righe (<tr> element) e non è necessario conservare informazioni duplicate nel <td> nascosto elemento in ogni riga.

Ci sono molte altre parti del tuo codice che potrebbero essere migliorate. Ad esempio l'operazione DELETE che usi sul lato server sembra essere strana. Usi mtype: 'DELETE' , ma invii l'ID della riga eliminata all'interno di body della richiesta al server invece di aggiungerla all'URL. Corrisponde agli standard, HTTP DELETE dovrebbe contenere nessun corpo . Puoi usare l'opzione jqGrid formDeleting per specificare tutte le opzioni Elimina e puoi definire url parametro come funzione:

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

È necessario modificare il codice del server di /RestWithDatabaseConnection/rest/delete/ utilizzare lo stesso protocollo di comunicazione e ottenere l'ID di cancellato dall'URL.

Puoi usare navOptions parametro di jqGrid libero per specificare le opzioni di navGrid :

navOptions: { edit: false, add: false }

(searchtext: 'Search' e altre opzioni che usi sembrano avere valori predefiniti e li ho rimossi).

Per essere più vicini agli standard REST, è possibile utilizzare l'operazione HTTP PUT per la modifica delle righe e HTTP POST per l'aggiunta di nuove righe. Dovresti implementare diversi punti di ingresso per entrambe le operazioni sul back-end. Usi /RestWithDatabaseConnection/rest/update già e puoi implementare /RestWithDatabaseConnection/rest/create per aggiungere nuove righe. Puoi utilizzare il seguente inlineEditing modifiche ad esempio per implementare lo scenario:

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