Poniżej znajduje się kilka rad, jak rozwiązać główny problem i ulepszyć kod JavaScript, który zamieściłeś.
Przede wszystkim generowanie nowych rowidów lokalnie jest wymagane w przypadku lokalnego scenariusza edycji. Należy wygenerować nowe wiersze na serwerze w przypadku zapisania danych na backendzie w bazie danych. Typowa implementacja polega na posiadaniu PRIMARY KEY zdefiniowany jako int IDENTITY w co stół. To sprawia, że identyfikatory są unikalne i stałe. Usunięcie jakiegoś wiersza i utworzenie nowego nigdy nie zostanie zinterpretowane jako edycja starego wiersza, ponieważ nowy wiersz otrzyma zawsze nowy identyfikator, który nigdy wcześniej nie był używany (w tabeli).
Aby skorzystać z identyfikatorów generowanych po stronie serwera jeden ma dwie główne możliwości:
- ponowne ładowanie siatki po każdej operacji dodawania wiersza.
- rozszerzenie komunikacji z serwerem przy edycji tak, aby serwer zwracał nowy identyfikator, wygenerowany w tabeli bazy danych, z powrotem do jqGrid. Można użyć
aftersavefuncwywołanie zwrotne (tylko dla Dodaj nowy wiersz) w celu zaktualizowania wiersza po pomyślnym utworzeniu wiersza na serwerze. Wiele standardowych implementacji usług RESTful zwraca pełne dane wiersza dołączany identyfikator zarówno w Dodaj, jak i Edytuj. Można użyć danych wewnątrzaftersavefuncwywołanie zwrotne i użyj czegoś takiego jak$("#" + rowid).attr("id", newRowid);aby zaktualizować nowy wiersz. Zapisano id w kilku dodatkowych kolumnach (tak jak używasz ukrytegoidkolumna) należy użyćsetCellmetoda dodatkowo, aby zaktualizować komórkę.
Pierwszy wybór jest w większości prosty i polecam go wdrożyć w pierwszej kolejności. Tylko jeśli przeładowanie siatki nie zadowoli użytkowników, którzy dodają wiele wierszy jeden po drugim, należy napisać trochę więcej kodu i wdrożyć drugi scenariusz.
Twój obecny kod używa inlineNav dla operacji Dodaj i Edytuj, zaimplementowanych przy użyciu edycji wbudowanej oraz metody navGrid dla operacji Usuń, realizowanej za pomocą edycji formularza. Edycja formularza, w tym Delete, używa reloadAfterSubmit: true opcja domyślna. Oznacza to, że siatka zostanie ponownie załadowana z serwera (z url: "/RestWithDatabaseConnection/rest/fetchData" ) po usunięciu każdego wiersza. Możesz rozwiązać swój główny problem, zastępując afterSaveFunction do następujących:
var afterSaveFunction = function () {
$(this).trigger("reloadGrid", [{current: true, fromServer: true}]);
};
Opcja current do zatrzymania aktualnego wyboru po ponownym załadowaniu i opcji fromServer: true mają sens tylko w przypadku, gdy używasz loadonce: true opcja dodatkowo. Możesz po prostu użyć reloadGridOptions: {fromServer: true} opcja navGrid aby wymusić ponowne załadowanie danych z serwera kliknij przycisk Odśwież/Załaduj ponownie na pasku nawigacyjnym. Jeśli nie masz tak dużo danych, które chcesz wyświetlić w siatce (na przykład mniej niż 1000 wierszy), takie zachowanie byłoby zalecane.
Kilka bardziej typowych porad dotyczących ulepszenia kodu:
Możesz rozważyć użycie height: "auto" zamiast height: 250 i zarządzać maksymalną wysokością siatki, określając rowNum wartość. Opcja scrollOffset: 0 będą niepotrzebne w przypadku.
Format danych zwracanych z serwera wygląda tak, że nie zaimplementowano stronicowania, sortowania i filtrowania po stronie serwera . Powinieneś użyć loadonce: true i forceClientSorting: true opcje. loadonce: true informuje jqGrid o zapisaniu wszystkich dane zwrócone z serwera lokalnie w wewnętrznych data parametr. Możesz w dowolnym momencie uzyskać dostęp do tablicy, używając $('#grid').jqGrid("getGridParam", "data") . Wartość rowNum (wartość domyślna to 20) zostanie użyta dla lokalnego stronicowanie. sortname i sortorder będzie używany dla lokalnego sortowanie. I użyjesz okna dialogowego wyszukiwania (dodane przez navGrid ) lub pasek narzędzi filtrów (dodany przez filterToolbar ) dla lokalnego wyszukiwanie/filtrowanie. Upraszcza kod serwera, poprawia wydajność sieci grid z punktu widzenia użytkownika i upraszcza interfejs między serwerem a klientem. Możesz używać klasycznego interfejsu RESTful na serwerze bez żadnych rozszerzeń.
Kolejna uwaga:polecam usunąć niepotrzebny ukryty id kolumna (name:'id', label:'id', key: true, hidden: true, ... ). Informacje o wierszu zostaną zapisane w id atrybut wierszy (<tr> element) i nie trzeba przechowywać zduplikowanych informacji w ukrytym <td> element w każdym rzędzie.
Istnieje wiele innych części twojego kodu, które można poprawić. Na przykład operacja DELETE, której używasz po stronie serwera, wydaje się dziwna. Używasz mtype: 'DELETE' , ale wysyłasz identyfikator usuniętego wiersza wewnątrz body żądania do serwera zamiast dołączania go do adresu URL. Odpowiada standardom, HTTP DELETE nie powinien zawierać żadnej treści . Możesz użyć opcji jqGrid formDeleting aby określić wszystkie opcje usuwania i możesz zdefiniować url parametr jako funkcja:
formDeleting: {
mtype: "DELETE",
url: function (rowid) {
return "/RestWithDatabaseConnection/rest/delete/" + rowid;
},
ajaxDelOptions: { contentType: "application/json" },
serializeDelData: function () {
return "";
}
}
Musisz zmienić kod serwera /RestWithDatabaseConnection/rest/delete/ używać tego samego protokołu komunikacyjnego i uzyskać identyfikator usuniętych z adresu URL.
Możesz użyć navOptions parametr wolnego jqGrid, aby określić opcje navGrid :
navOptions: { edit: false, add: false }
(searchtext: 'Search' i inne opcje, których używasz, wydają się mieć wartości domyślne i tam usunąłem).
Aby być bliżej standardów REST można użyć operacji HTTP PUT do edycji wierszy i HTTP POST do dodawania nowych wierszy. Powinieneś zaimplementować różne punkty wejścia dla obu operacji na zapleczu. Używasz /RestWithDatabaseConnection/rest/update już i możesz zaimplementować /RestWithDatabaseConnection/rest/create do dodawania nowych wierszy. Możesz użyć następującej inlineEditing zmiany na przykład w celu realizacji scenariusza:
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);
}
}
}
}