jqGrid: как обновить идентификатор строки, если столбцы первичного ключа редактировались

Значения первичных ключей используются как идентификаторы строк в данных json, возвращаемых сервером. Если значение первичного ключа редактируется и сохраняется два раза, второе сохранение вызывает ошибку, поскольку jqGrid снова передает исходное значение первичного ключа методу редактирования.

Как обновить идентификатор строки jqGrid до нового значения первичного ключа, если значение первичного ключа изменено при встроенном редактировании?

$(function () {
        var grid = $("#grid");
        grid.jqGrid({
                url: '<%= ResolveUrl("~/Grid/GetData?_entity=Strings")%>',
                datatype: "json",
                mtype: 'POST',
                scroll: 1,
                autoencode: true,
                colModel: [{
                    name: 'Source',
                    fixed: true,
                    editable: true,
                    width: 30
                }, { /* this is primary key passed also as id */
                    name: 'Est',
                    fixed: true,
                    editable: true,
                    width: 271
                }, {
                    name: 'Eng',
                    fixed: true,
                    editable: true,
                    width: 167
                }],
                gridview: true,
                pager: '#pager',
                viewrecords: true,
                editurl: '<%= ResolveUrl("~/Grid/Edit?_entity=Strings")%>',
        ...

person Andrus    schedule 29.05.2011    source источник
comment
Если для редактирования используется отдельная форма, мы можем использовать reloadAfterSubmit: true, который обновляет id. Мабе можно как-нибудь обновить встроенную редактируемую строку. Или мы можем изменить идентификатор строки после завершения запроса метода редактирования   -  person Andrus    schedule 30.05.2011


Ответы (1)


Rowid - это не что иное, как значение атрибута id соответствующего <tr> элемента сетки. Итак, чтобы изменить rowid oldRowid на newRowid, вы должны сделать что-то вроде следующего:

$("#" + oldRowid).attr("id", newRowid);
person Oleg    schedule 29.05.2011
comment
идентификаторы строк создаются из всех столбцов первичного ключа и кодируются для удаления символов, недопустимых в идентификаторах строк. Какое событие следует использовать для замены идентификатора строки? Как найти предыдущие и новые значения идентификаторов строк для замены? - person Andrus; 30.05.2011
comment
@Andrus: удаление или экранирование специальных символов необходимо только в том случае, если вы напишете общее решение, которое будет использовать других людей, которые не совсем понимают, что он делает. В вашем собственном решении вы, конечно, должны использовать как ids более разумные значения. Таким образом, вам никогда не понадобится проблема с экранированием символов. Если у вас есть проблема, вы должны использовать $.jgrid.jqID. - person Oleg; 30.05.2011
comment
@Andrus: на вопрос о мероприятии нельзя ответить, не зная контекста. Например, важно знать, какой режим редактирования вы используете. Более того, я ответил вам только для того, чтобы показать, как вообще можно решить проблему с редактированием id. Я не думаю, что это нужно когда-либо делать. Каждый хороший дизайн базы данных означает, что идентификаторы никогда не должны изменяться. - person Oleg; 30.05.2011
comment
@Oleg: в вопросе указано, что используется встроенное редактирование. База данных использует естественные первичные ключи. Идентификаторы строк создаются на сервере путем усечения столбцов составного ключа. Можно дублировать столбцы составного ключа как скрытые столбцы, если это может упростить изменение идентификатора. Следует ли использовать editRow aftersavefunc? Должен ли обработчик метода редактирования сервера возвращать новый идентификатор строки, чтобы aftersavefunc мог выполнить изменение идентификатора строки? - person Andrus; 30.05.2011
comment
@Andrus: В случае встроенного редактирования aftersavefunc - хорошее место. Вы, сервер, просто устанавливаете новый id в качестве значения Est, введенного сервером, который вам не нужен (но может, если существуют другие требования), отправлять любую дополнительную информацию на сервер. О естественных первичных ключах: пользователи не знают, что такое первичный ключ, поэтому это только часть дизайна базы данных. В многопользовательской среде лучшими (естественными) ключами являются целочисленные автоинкременты. Это мое убеждение. Места здесь слишком мало для подробностей. - person Oleg; 30.05.2011
comment
@Oleg: Я модифицировал контроллер, чтобы он возвращал новый идентификатор строки, и созданное окно предупреждения function aftersavefunc(rowID, response) { alert( 'old: '+ rowID + '\nNew: '+ response.responseText ); $("#"+rowID).attr("id", response.responseText); } показывает, что переданы правильные идентификаторы. Однако при повторном сохранении строки исходный идентификатор строки снова передается на сервер. Похоже, эта команда не меняет rowID. Как заставить jqGrid передавать правильный идентификатор строки при втором сохранении? - person Andrus; 30.05.2011
comment
@Andrus: Если вы разместите URL-адрес своего решения, я могу попытаться отладить его, чтобы выяснить причину. - person Oleg; 30.05.2011
comment
@Oleg: Я отправляю вам testcase, используя контактный адрес электронной почты вашей компании. - person Andrus; 31.05.2011
comment
@Andrus: моя электронная почта [email protected] - person Oleg; 31.05.2011
comment
@Andrus: Я сообщил вам, что в настоящее время вы используете некоторые символы в идентификаторе, необходимо экранировать если они используются в селекторах jQuery. Таким образом, вы должны заменить в своей функции aftersavefunc оператор $("#"+rowID).attr("id", response.responseText); на $("#"+rowID.replace(/([\.\+\%\:\[\]])/g,"\\$1")).attr("id", response.responseText);. Если вы используете больше специальных символов в id, вам следует расширить код. Лучше всего использовать INT AUTOINCREMENT (int IDENTITY(1,1) NOT NULL) в качестве определения первичного ключа во всех таблицах. - person Oleg; 01.06.2011
comment
@Oleg: справка по селектору jquery не предоставляет полный список метасимволов. Он писал: Если вы хотите использовать какой-либо из метасимволов (например,! # $% & '() * +,. / :; ‹=›? @ [] ^ `{|} ~). Я изменил контроллер, чтобы кодировать все неанглийские буквы и цифры в идентификаторах строк. Кажется, это решило проблему. Я пометил ваш ответ как ответ. Спасибо. - person Andrus; 01.06.2011
comment
@Andrus: Я рекомендую вам изменить дизайн таблиц базы данных, чтобы использовать автоинкрементные целочисленные идентификаторы (на MS SQL Server int IDENTITY(1,1) NOT NULL тип данных). Вы можете легко расширить существующие таблицы с помощью идентификаторов. Это сэкономит много времени в будущем, особенно в многопользовательской среде и в качестве базы данных для веб-приложений. Кроме того, я бы порекомендовал вам включить столбец timestamp (rowversion), не допускающий значения NULL, во все таблицы и использовать его для оптимистичного параллелизма. Если вы не уверены, действительно ли это хорошо, вы можете просто задать новый вопрос о stackoverflow и прочитать мнения других пользователей. - person Oleg; 01.06.2011
comment
@Oleg: У меня есть существующая схема базы данных, развернутая на сотнях сайтов с существующим приложением на каждом из этих сайтов. Схема использует естественные ключи примерно для 20 таблиц. Работает много лет. Рефакторинг этой схемы и изменение приложения - огромная работа. Также Джоэл Селко звонит людям, которые помещают столбец id в каждую таблицу id-iots в своей книге SQL. Так что рефакторинг БД нецелесообразен. - person Andrus; 03.06.2011
comment
@Andrus: Я не знаю, в какой среде вы находитесь, но я все еще думаю, что вам нужно сделать изменение закрытого ключа или добавление нового столбца INT IDENTIFY и соответствующего ограничения UNIQUE в новый столбец. Добавление нового столбца в основном является прозрачным для старых приложений, и все они продолжают работать. Ограничение UNIQUE почти то же самое, что и первичный ключ, и его можно использовать для идентификации строки данных. В jqGrid вы можете использовать новый столбец как id и без проблем. Вы можете легко сгенерировать скрипт с пустой БД и отправить мне, я покажу, что я имею в виду, на примере. - person Oleg; 03.06.2011
comment
Также Джоэл Селко звонит людям, которые помещают столбец id в каждую таблицу id-iot в своей книге SQL. Я слышал это несколько раз, но никогда не было веских причин для этого. Это больше похоже на идею «пуриста данных», в то время как IRL часто очень удобно иметь автоматическое увеличение int в качестве первичного ключа по причинам, которые вы в настоящее время обнаруживаете. - person Brandon; 01.07.2011
comment
@Brandon: Какую книгу Джоэла Селко вы цитируете именно? Когда была опубликована книга? При разработке веб-приложений очень важна реализация параллелизма, но старый подход с блокировкой объектов базы данных очень опасен в веб-приложениях. Итак, можно использовать подход оптимистичного параллелизма. В случае, если у вас должно быть больше уникальности в данных. Использование int IDENTITY(1,1) NOT NULL в качестве идентификатора и дополнительного столбца timestamp (rowversion), не допускающего значения NULL, помогает. Посмотрите здесь. - person Oleg; 01.07.2011
comment
@ Олег Я цитировал Андруса. Да, универсальные уникальные идентификаторы (первичные ключи) имеют некоторые преимущества, но, на мой взгляд, любые преимущества перевешиваются дополнительной сложностью управления нечисловыми первичными ключами и накладными расходами на запоминание / поиск каждой таблицы, поле которой является первичным ключом. С числовым автоматически увеличивающимся ключом объединения, внешние ключи и некоторые другие общие задачи, такие как получение самой новой строки, становятся тривиальными, а с нечисловыми ключами - не так много. - person Brandon; 07.07.2011
comment
@Brandon: Извините, но я не уверен, что смогу полностью подписаться на вас. Я думаю, что выбор первичного ключа должен быть показан в контексте. В настоящее время у Андруса есть таблицы с длинным английским текстом в первом столбце, объявленном как первичный ключ, и многие другие столбцы, содержащие переводы текста на другие языки. Если я правильно понимаю, он использует такую ​​таблицу для локализации текстов в своем приложении. Такой вид очень длинного текста, как первичный ключ, 1) медленный в SQL при индексации 2) у него есть идентификатор проблемы, который в некоторых случаях будет добавлен к URL-адресу 3) изменение английского текста следует за изменением идентификатора. - person Oleg; 07.07.2011
comment
@Brandon: он перестраивает индекс и усложняет работу в многопользовательской среде (проблемы параллелизма). Поэтому в этой ситуации я рекомендовал Андрусу использовать int IDENTITY(1,1) NOT NULL в качестве первичного ключа или в качестве дополнительного столбца, не допускающего значения NULL, и поместить в столбец УНИКАЛЬНОЕ ОГРАНИЧЕНИЕ. Так он сможет найти текст по значению столбца. Он может использовать значение по крайней мере как id строки jqGrid. В пути он решит дополнительную проблему с экранированием специальных символов в rowid jaGrid. - person Oleg; 07.07.2011
comment
@Oleg Он должен вас выслушать, я не пытаюсь противоречить вашим рекомендациям для этой конкретной ситуации, а просто комментирую общий случай: стоит ли с самого начала включать числовой первичный ключ. Андрес предположил, что это не так, однако я не могу найти никаких веских причин для этого выбора, хотя я слышал это несколько раз раньше. - person Brandon; 08.07.2011