Níže uvádíme několik rad, jak vyřešit váš hlavní problém a zlepšit kód JavaScript, který jste zveřejnili.
Za prvé, generování nových rowidů lokálně je vyžadován pro scénář místní úpravy. Měli byste vygenerovat nové rowid na serveru v případě uložení dat na backendu do databáze. Typická implementace spočívá v tom, že máte PRIMARY KEY
definován jako int IDENTITY
v každém stůl. Díky tomu jsou ID jedinečná a pevná. Smazání některého řádku a vytvoření nového nebude nikdy interpretováno jako úprava starého řádku, protože nový řádek získá vždy nové id, které nebylo nikdy předtím použito (v tabulce).
Chcete-li mít výhodu ID generovaných na straně serveru jeden má dvě hlavní možnosti:
- znovu načtení mřížky po každé operaci Přidat řádek.
- rozšíří komunikaci se serverem při úpravách tak, aby server vrátil nové id vygenerované v databázové tabulce zpět do jqGrid. Lze použít
aftersavefunc
zpětné volání (pouze pro Přidat nový řádek) pro aktualizaci rowid po úspěšném vytvoření řádku na serveru. Mnoho standardních implementací služeb RESTful vrací úplná data řádku včetně id na Přidat nebo Upravit. Je možné použít data uvnitřaftersavefunc
zpětné volání a použijte něco jako$("#" + rowid).attr("id", newRowid);
pro aktualizaci nového řádku. Uložil id do některých dalších sloupců (jako když používáte skrytéid
sloupec), pak byste měli použítsetCell
metoda dodatečně aktualizovat buňku.
První volba je většinou jednoduchá a doporučil bych vám ji implementovat jako první. Pouze pokud opětovné načtení mřížky neuspokojí uživatele, kteří přidávají mnoho řádků jeden za druhým, měli byste napsat trochu více kódu a implementovat druhý scénář.
Váš aktuální kód používá inlineNav
pro operace Add and Edit implementované pomocí inline editace a metody navGrid
pro operaci Delete, implementovanou pomocí editace formuláře. Úprava formuláře, včetně Delete, používá reloadAfterSubmit: true
možnost ve výchozím nastavení. Znamená to, že mřížka bude znovu načtena ze serveru (z url: "/RestWithDatabaseConnection/rest/fetchData"
) po smazání každého řádku. Svůj hlavní problém můžete vyřešit nahrazením afterSaveFunction
na následující:
var afterSaveFunction = function () {
$(this).trigger("reloadGrid", [{current: true, fromServer: true}]);
};
Možnost current
podržte aktuální výběr po opětovném načtení a volbu fromServer: true
má smysl pouze v případě, že použijete loadonce: true
možnost dodatečně. Stačí použít reloadGridOptions: {fromServer: true}
možnost navGrid
vynutit opětovné načtení dat ze serveru po kliknutí na tlačítko Obnovit/Znovu načíst na navigační liště. Pokud nemáte tolik dat, která potřebujete zobrazit v mřížce (například méně než 1000 řádků), takové chování by bylo doporučeno.
Některé další běžné rady pro vylepšení kódu:
Můžete zvážit použití height: "auto"
místo height: 250
a pro správu maximální výšky mřížky zadáním rowNum
hodnota. Možnost scrollOffset: 0
bude v tomto případě nepotřebná.
Formát dat vrácených ze serveru vypadá tak, že neimplementujete stránkování, řazení a filtrování na straně serveru . Měli byste použít loadonce: true
a forceClientSorting: true
možnosti. loadonce: true
informuje jqGrid o uložení všech data vrácená ze serveru lokálně v interních data
parametr. K poli můžete kdykoli přistupovat pomocí $('#grid').jqGrid("getGridParam", "data")
. Hodnota rowNum
(výchozí hodnota je 20) bude použita pro místní stránkování. sortname
a sortorder
bude použit pro místní třídění. A použijete vyhledávací dialog (přidaný pomocí navGrid
) nebo panel nástrojů filtru (přidaný pomocí filterToolbar
) pro místní vyhledávání/filtrování. Zjednodušuje kód serveru, zlepšuje výkon gridu z pohledu uživatele a zjednodušuje rozhraní mezi serverem a klientem. Na serveru můžete používat klasické rozhraní RESTful bez jakýchkoli rozšíření.
Další poznámka:Doporučil bych vám odstranit nepotřebné skryté id
sloupec (name:'id', label:'id', key: true, hidden: true, ...
). Informace o rowid budou uloženy v id
atribut řádků (<tr>
prvek) a není třeba uchovávat duplicitní informace ve skrytém <td>
prvek v každém řádku.
Existuje mnoho dalších částí vašeho kódu, které by mohly být vylepšeny. Například operace DELETE, kterou používáte na straně serveru, se zdá být zvláštní. Používáte mtype: 'DELETE'
, ale odešlete ID smazaného řádku uvnitř body požadavku na server namísto jeho připojení k URL. V souladu se standardy by HTTP DELETE neměl obsahovat žádné tělo . Můžete použít volbu jqGrid formDeleting
specifikovat všechny možnosti Delete a můžete definovat url
parametr jako funkce:
formDeleting: {
mtype: "DELETE",
url: function (rowid) {
return "/RestWithDatabaseConnection/rest/delete/" + rowid;
},
ajaxDelOptions: { contentType: "application/json" },
serializeDelData: function () {
return "";
}
}
Musíte z důvodu upravit kód serveru /RestWithDatabaseConnection/rest/delete/
používat stejný komunikační protokol a získat id smazané z adresy URL.
Můžete použít navOptions
parametr free jqGrid k určení možností navGrid
:
navOptions: { edit: false, add: false }
(searchtext: 'Search'
a další možnosti, které používáte, mají zřejmě výchozí hodnoty a já jsem je tam odstranil).
Pro přiblížení se standardům REST lze použít operaci HTTP PUT pro editaci řádků a HTTP POST pro přidávání nových řádků. Měli byste implementovat jiné vstupní body pro obě operace na backendu. Používáte /RestWithDatabaseConnection/rest/update
již a můžete implementovat /RestWithDatabaseConnection/rest/create
pro přidání nových řádků. Můžete použít následující inlineEditing
změny například pro implementaci scénáře:
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);
}
}
}
}