Была введена опция idPrefix
для хранения идентификаторов на HTML-странице , уникальных даже для тех идентификаторов, которые были загружены с сервера. Типичный пример - две сетки с данными, загруженными с сервера. Позвольте нам иметь две таблицы в базе данных, где вы используете IDENTITY или AUTOINCREMENT в определении PRIMARY KEY
. В случае, если первичный ключ будет сгенерирован автоматически в таблице и будет уникальным внутри таблицы, но не существует уникальных над таблиц. Поэтому, если вы используете первичные ключи в качестве идентификаторов сеток и размещаете на одной странице две сетки, вы можете иметь дубликаты идентификаторов.
Чтобы решить эту проблему, вы можете использовать idPrefix: "a"
в качестве дополнительной опции в первой сетке и использовать idPrefix: "b"
во второй сетке. В случае, если локально jqGrid будет везде использовать идентификаторы с префиксом, но префикс будет обрезан, если идентификаторы будут отправлены на сервер .
Таким образом, вы будете локально видеть во всех обратных вызовах (событиях) и во всех методах (например, setRowData
, addRowData
и т. Д.) Идентификаторы с префиксом , а на стороне сервера идентификаторы - префиксы будут удалены непосредственно перед отправкой на сервер.
Я рекомендую вам дополнительно прочитать другой ответ об ограничениях в идентификаторах, которые я разместил сегодня.
ОБНОВЛЕНО : Я просмотрел код, который вы задали на jsfiddle, и обнаружил некоторые явные ошибки в вашем коде. Ваш текущий код
1) использовать неверный алгоритм для генерации идентификатора новой строки. Например, следующий код
// generic way to create an animal
function newAnimal(collection, defaults) {
var next = collection.length + 1;
var newpet = {
id : next,
name: defaults.name + next,
breed: defaults.breed
};
return newpet;
}
используйте collection.length + 1
для нового идентификатора. Это неправильно, если вы разрешаете удалять элементы. Добавляя два элемента, удаляя один оттуда и добавляя новый элемент, следует еще раз идентифицировать дубликаты идентификаторов. Вместо этого более безопасно использовать некоторую переменную, которая будет только увеличиваться. Вы можете использовать $. Jgrid.randId () , например, какой код очень прост.
2) вы звоните addRowData
с , добавляя префикс вручную (см. dogsPrefix+newdog.id
ниже). Это неправильно, потому что jqGrid добавляет префикс еще раз к строкам.
// add dog button actions
$('#dogAddAtEnd').click(function() {
var newdog = newAnimal(dogs, dogDefaults);
dogs.push(newdog);
dogAdded();
dogsTable.jqGrid('addRowData', dogsPrefix+newdog.id, newdog);
});
Возможно, есть еще проблемы, но, по крайней мере, эти проблемы могут объяснить проблемы, которые вы описали.
ОБНОВЛЕНО 2 : я изучил новое демо , которое вы разместили. У него есть еще строки
grid.jqGrid('addRowData', newanimal.id, newanimal,
"after", prefix+ followingId);
и
dogsTable.jqGrid('addRowData', dogsPrefix+newdog.id, newdog);
, который должен быть зафиксирован на
grid.jqGrid('addRowData', newanimal.id, newanimal,
"after", followingId);
и
dogsTable.jqGrid('addRowData', newdog.id, newdog);
Тем не менее я протестировал демо после изменений и обнаружил ошибки в коде addRowData
, delRowData
и setRowData
. Проблема в строке из delRowData
и в одной строке из setRowData
var pos = $t.p._index[rowid];
можно установить на следующее
var id = $.jgrid.stripPref($t.p.idPrefix, rowid), pos = $t.p._index[id];
Внутри addRowData
Предлагаю включить строку
var id = rowid; // pure id without prefix
до строки
rowid = t.p.idPrefix + rowid;
из addRowData
. Другие буксирные линии из addRowData
lcdata[t.p.localReader.id] = rowid;
t.p._index[rowid] = t.p.data.length;
следует изменить на
lcdata[t.p.localReader.id] = id;
t.p._index[id] = t.p.data.length;
где будет использоваться идентификатор без префикса.
Модифицированный код вашей демонстрации, который использует фиксированную версию jquery.jqGrid.src.js , которую вы можете протестировать здесь .
Я опубликую свой отчет об ошибке в trirand позже, чтобы сообщить разработчику jqGrid. Я надеюсь, что скоро исправление будет включено в основной код jqGrid.
Дополнительно я рекомендую использовать метод $.jgrid.stripPref
для удаления префиксов из rowids. Например, функция
//general delete selected
function deleteSelectedAnimal(list, grid, prefix)
{
var sel = grid.jqGrid('getGridParam', 'selrow');
if (sel.length)
{
var gridrow = sel;
//get the unprefixed model id
var modelid = gridrow;
if (prefix.length !== 0)
{
modelid = modelid.split(prefix)[1];
}
// make it a numeric
modelid = Number(modelid);
//delete the row in the collection
list = RemoveAnimal(list, modelid);
//delete the row in the grid
grid.jqGrid('delRowData', gridrow);
}
}
с ваше демо можно переписать на следующее
//general delete selected
function deleteSelectedAnimal(list, grid)
{
var sel = grid.jqGrid('getGridParam', 'selrow'),
gridPrefix = grid.jqGrid('getGridParam', 'idPrefix');
if (sel !== null)
{
//delete the row in the collection
// ??? the gogs list will be not modified in the way !!!
list = RemoveAnimal(list, $.jgrid.stripPref(gridPrefix, sel));
//delete the row in the grid
grid.jqGrid('delRowData', sel);
}
}
Я не уверен, что строка list = RemoveAnimal(list, $.jgrid.stripPref(gridPrefix, sel));
или функция RemoveAnimal
делают то, что вы хотите, но это не проблема, связанная с jqGrid.
Еще одно небольшое замечание о вашем коде.Вы уже используете в объектах, которые добавляете в сетку, свойство id
.Это то же имя, которое определено в localReader.id .В случае, если данные из свойства id
будут использоваться как атрибут id
строк сетки (<tr>
).Локальный параметр data
сохранит id
дополнительно к другим свойствам, созданным из свойства name
элементов colModel
.Поэтому я не вижу смысла определять скрытый столбец
{ key: true, name: 'id', align: 'left', hidden: true }
Как вы можете видеть на демо все остальное работает так же, как и раньше, если вы удалите id
столбециз сеток, которые вы используете.
ОБНОВЛЕНО 3 : Как и было обещано ранее, я опубликовал соответствующий отчет об ошибке здесь .