Nedenfor er nogle råd til at løse dit hovedproblem og for at forbedre den JavaScript-kode, som du har sendt.
Først og fremmest genereringen af nye rowids lokalt er påkrævet til lokal redigeringsscenarie. Man bør generere de nye rækker på serveren i tilfælde af at gemme dataene på backend i databasen. Typisk implementering består i at have PRIMARY KEY
defineret som int IDENTITY
i hver bord. Det gør id'erne unikke og faste. Sletning af en række og oprettelse af den nye vil aldrig blive tolket som redigering af den gamle række, fordi den nye række altid får et nyt id, som aldrig blev brugt før (i tabellen).
For at have fordel af id'er genereret på serversiden man har to hovedvalg:
- genindlæser gitteret efter hver Tilføj række-handling.
- udvidelse af kommunikationen med serveren ved redigering, så serveren returnerer nyt id, genereret i databasetabellen, tilbage til jqGrid. Man kan bruge
aftersavefunc
tilbagekald (kun for Tilføj ny række) for at opdatere rækken efter vellykket oprettelse af rækken på serveren. Mange standardimplementeringer af RESTful-tjenester returnerer hele rækkedata tilbage inklusive id på både Tilføj eller Rediger. Man kan bruge data inde iaftersavefunc
tilbagekald og brug noget som$("#" + rowid).attr("id", newRowid);
for at opdatere den nye række. Den gemte id'et i nogle ekstra kolonner (som du bruger skjultid
kolonne), så skal man brugesetCell
metode til også at opdatere cellen.
Det første valg er det mest simple, og jeg vil anbefale dig at implementere det først og fremmest. Kun hvis genindlæsning af gitteret ikke vil tilfredsstille brugerne, som tilføjer mange rækker efter hinanden, så skal du skrive lidt mere kode og implementere det andet scenario.
Din nuværende kode bruger inlineNav
til tilføjelses- og redigeringsoperationer, implementeret ved hjælp af inline-redigering, og metoden navGrid
for sletning, implementeret ved hjælp af formularredigering. Formularredigering, inklusive Slet, bruger reloadAfterSubmit: true
mulighed som standard. Det betyder, at gitteret vil blive genindlæst fra serveren (fra url: "/RestWithDatabaseConnection/rest/fetchData"
) efter sletning af hver række. Du kan løse dit hovedproblem ved at erstatte afterSaveFunction
til følgende:
var afterSaveFunction = function () {
$(this).trigger("reloadGrid", [{current: true, fromServer: true}]);
};
Indstillingen current
for at holde det aktuelle valg efter genindlæsning og muligheden fromServer: true
har kun mening i tilfælde, hvis du bruger loadonce: true
mulighed yderligere. Du kan bare bruge reloadGridOptions: {fromServer: true}
mulighed for navGrid
for at tvinge genindlæsning af data fra serveren klik på knappen Opdater/Genindlæs på navigatorlinjen. Hvis du ikke har så mange data, som du skal vise i gitteret (for eksempel mindre som 1000 rækker), vil en sådan adfærd anbefales.
Nogle mere almindelige råd til dig for at forbedre din kode:
Du kan overveje at bruge height: "auto"
i stedet for height: 250
og for at styre den maksimale højde af gitteret ved at angive rowNum
værdi. Indstillingen scrollOffset: 0
vil være unødvendig i sagen.
Formatet på de data, der returneres fra serveren, ser sådan ud, at du ikke implementerer sidesøgning, sortering og filtrering på serversiden . Du skal bruge loadonce: true
og forceClientSorting: true
muligheder. loadonce: true
informerer jqGrid om at gemme alle de data, der returneres fra serveren lokalt i interne data
parameter. Du kan til enhver tid få adgang til arrayet ved at bruge $('#grid').jqGrid("getGridParam", "data")
. Værdien af rowNum
(standardværdien er 20) vil blive brugt til lokal personsøgning. sortname
og sortorder
vil blive brugt til lokal sortering. Og du vil bruge søgedialogen (tilsat af navGrid
) eller filterværktøjslinjen (tilføjet af filterToolbar
) for lokal søgning/filtrering. Det forenkler serverkoden, forbedrer ydeevnen af nettet fra brugerens synspunkt og forenkler grænsefladen mellem serveren og klienten. Du kan bruge den klassiske RESTful-grænseflade på serveren uden nogen udvidelser.
En anden bemærkning:Jeg vil anbefale dig at fjerne unødvendigt skjult id
kolonne (name:'id', label:'id', key: true, hidden: true, ...
). Oplysningerne om rowiden vil blive gemt i id
rækkernes attribut (<tr>
element), og man behøver ikke at opbevare duplikerede oplysninger i den skjulte <td>
element i hver række.
Der er mange andre dele af din kode, som kunne forbedres. For eksempel virker SLET-operationen, som du bruger på serversiden, mærkelig. Du bruger mtype: 'DELETE'
, men du sender id'et for den slettede række inde i body af anmodningen til serveren i stedet for at tilføje den til URL'en. Svarer til standarderne, HTTP DELETE bør indeholde ingen krop . Du kan bruge jqGrid-indstillingen formDeleting
for at angive alle Slet-indstillinger, og du kan definere url
parameter som funktion:
formDeleting: {
mtype: "DELETE",
url: function (rowid) {
return "/RestWithDatabaseConnection/rest/delete/" + rowid;
},
ajaxDelOptions: { contentType: "application/json" },
serializeDelData: function () {
return "";
}
}
Du skal af årsag ændre din serverkode for /RestWithDatabaseConnection/rest/delete/
at bruge den samme kommunikationsprotokol og for at få slettet id'et fra URL'en.
Du kan bruge navOptions
parameter for free jqGrid for at specificere mulighederne for navGrid
:
navOptions: { edit: false, add: false }
(searchtext: 'Search'
og andre muligheder, som du bruger, ser ud til at have standardværdier, og jeg fjernede der).
For at være tættere på REST-standarder kan man bruge HTTP PUT-operation til rækkeredigering og HTTP POST til at tilføje nye rækker. Du bør implementere anderledes indgangspunkter for begge operationer på backend. Du bruger /RestWithDatabaseConnection/rest/update
allerede, og du kan implementere /RestWithDatabaseConnection/rest/create
for at tilføje nye rækker. Du kan bruge følgende inlineEditing
ændringer for eksempel for at implementere scenariet:
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);
}
}
}
}