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ć
aftersavefunc
wywoł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ątrzaftersavefunc
wywoł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 ukrytegoid
kolumna) należy użyćsetCell
metoda 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);
}
}
}
}