Mysql
 sql >> Datenbank >  >> RDS >> Mysql

jqGrid - Eindeutige ID für neue Zeile

Nachfolgend finden Sie einige Ratschläge zur Lösung Ihres Hauptproblems und zur Verbesserung des von Ihnen geposteten JavaScript-Codes.

Zunächst einmal die Generierung neuer Rowids lokal ist für das lokale Bearbeitungsszenario erforderlich. Man sollte die neuen Rowids auf dem Server generieren bei Speicherung der Daten am Backend in der Datenbank. Eine typische Implementierung besteht darin, PRIMARY KEY zu haben definiert als int IDENTITY in jedem Tisch. Es macht die IDs eindeutig und fest. Das Löschen einer Zeile und das Erstellen einer neuen wird niemals als Bearbeiten der alten Zeile interpretiert, da die neue Zeile immer eine neue ID erhält, die noch nie zuvor (in der Tabelle) verwendet wurde.

Um von auf der Serverseite generierten IDs profitieren zu können Man hat zwei Hauptmöglichkeiten:

  1. Neues Laden des Rasters nach jeder Operation "Zeile hinzufügen".
  2. Erweitern der Kommunikation mit dem Server beim Bearbeiten, sodass der Server eine neue, in der Datenbanktabelle generierte ID an jqGrid zurückgibt. Man kann aftersavefunc verwenden Rückruf (nur für Neue Zeile hinzufügen) zum Aktualisieren der Zeilen-ID nach dem erfolgreichen Erstellen der Zeile auf dem Server. Viele Standardimplementierungen von RESTful-Diensten geben vollständige Zeilendaten zurück inklusive ID sowohl beim Hinzufügen als auch beim Bearbeiten. Man kann die Daten innerhalb von aftersavefunc verwenden Callback und verwenden Sie so etwas wie $("#" + rowid).attr("id", newRowid); um die neue Zeile zu aktualisieren. Es wurde die ID in einigen zusätzlichen Spalten gespeichert (wie Sie versteckte id verwenden Spalte), dann sollte man setCell verwenden Methode zusätzlich, um auch die Zelle zu aktualisieren.

Die erste Wahl ist die meist einfache und ich würde Ihnen empfehlen, diese erst einmal umzusetzen. Nur wenn das Neuladen des Grids die Benutzer nicht zufrieden stellt, die viele Zeilen nacheinander hinzufügen, sollten Sie etwas mehr Code schreiben und das zweite Szenario implementieren.

Ihr aktueller Code verwendet inlineNav für Add- und Edit-Operationen, implementiert durch Inline-Bearbeitung, und die Methode navGrid für den Löschvorgang, der über die Formularbearbeitung implementiert wird. Die Formularbearbeitung, einschließlich Löschen, verwendet reloadAfterSubmit: true Option standardmäßig. Das bedeutet, dass das Grid vom Server neu geladen wird (von url: "/RestWithDatabaseConnection/rest/fetchData"). ) nach dem Löschen jeder Zeile. Sie können Ihr Hauptproblem lösen, indem Sie afterSaveFunction ersetzen zu Folgendem:

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

Die Option current um die aktuelle Auswahl nach dem Neuladen zu halten und die Option fromServer: true nur sinnvoll, wenn Sie loadonce: true verwenden Möglichkeit zusätzlich. Sie können einfach reloadGridOptions: {fromServer: true} verwenden Option von navGrid um das Neuladen der Daten vom Server zu erzwingen Klicken Sie auf die Schaltfläche Aktualisieren/Neu laden in der Navigationsleiste. Wenn Sie nicht so viele Daten haben, die Sie im Raster anzeigen müssen (z. B. weniger als 1000 Zeilen), wird ein solches Verhalten empfohlen.

Einige allgemeinere Ratschläge zur Verbesserung Ihres Codes:

Sie können erwägen, height: "auto" zu verwenden statt height: 250 und um die maximale Höhe des Rasters zu verwalten, indem Sie rowNum angeben Wert. Die Option scrollOffset: 0 wird in dem Fall nicht benötigt.

Das Format der vom Server zurückgegebenen Daten sieht so aus, dass Sie kein serverseitiges Paging, Sortieren und Filtern implementieren . Sie sollten loadonce: true verwenden und forceClientSorting: true Optionen. Der loadonce: true weist jqGrid an, alles zu speichern die vom Server zurückgegebenen Daten lokal in internen data Parameter. Sie können jederzeit auf das Array zugreifen, indem Sie $('#grid').jqGrid("getGridParam", "data") verwenden . Der Wert von rowNum (der Standardwert ist 20) wird für local verwendet Paging. Der sortname und die sortorder wird für lokal verwendet Sortierung. Und Sie werden den Suchdialog verwenden (hinzugefügt von navGrid ) oder die Filtersymbolleiste (hinzugefügt durch filterToolbar ) für lokal suchen/filtern. Es vereinfacht den Servercode, verbessert die Leistung des Grids aus der Sicht des Benutzers und vereinfacht die Schnittstelle zwischen dem Server und dem Client. Sie können die klassische RESTful-Schnittstelle auf dem Server ohne Erweiterungen verwenden.

Noch eine Anmerkung:Ich würde Ihnen empfehlen, nicht benötigte versteckte id zu entfernen Spalte (name:'id', label:'id', key: true, hidden: true, ... ). Die Information über die Rowid wird in id gespeichert Attribut der Zeilen (<tr> -Element) und man muss keine doppelten Informationen im versteckten <td> enthalten Element in jeder Zeile.

Es gibt viele andere Teile Ihres Codes, die verbessert werden könnten. Zum Beispiel scheint die DELETE-Operation, die Sie auf der Serverseite verwenden, seltsam zu sein. Sie verwenden mtype: 'DELETE' , aber Sie senden die ID der gelöschten Zeile innerhalb von body der Anfrage an den Server, anstatt sie an die URL anzuhängen. Entspricht den Standards, das HTTP DELETE sollte kein Body enthalten . Sie können die jqGrid-Option formDeleting verwenden um alle Löschoptionen anzugeben und Sie können url definieren Parameter als Funktion:

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

Sie müssen unbedingt Ihren Servercode von /RestWithDatabaseConnection/rest/delete/ ändern um dasselbe Kommunikationsprotokoll zu verwenden und um die ID von gelöscht von aus der URL zu erhalten.

Sie können navOptions verwenden Parameter von free jqGrid, um die Optionen von navGrid anzugeben :

navOptions: { edit: false, add: false }

(searchtext: 'Search' und andere Optionen, die Sie verwenden, scheinen Standardwerte zu haben und ich habe sie dort entfernt).

Um den REST-Standards näher zu kommen, kann man die HTTP-PUT-Operation zum Bearbeiten von Zeilen und HTTP-POST zum Hinzufügen neuer Zeilen verwenden. Sie sollten anders implementieren Einstiegspunkte für beide Vorgänge im Backend. Sie verwenden /RestWithDatabaseConnection/rest/update bereits und Sie können /RestWithDatabaseConnection/rest/create implementieren zum Hinzufügen neuer Zeilen. Sie können das folgende inlineEditing verwenden Änderungen zum Beispiel um das Szenario zu implementieren:

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