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:
- Neues Laden des Rasters nach jeder Operation "Zeile hinzufügen".
- 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 vonaftersavefunc
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 versteckteid
verwenden Spalte), dann sollte mansetCell
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);
}
}
}
}