#asp.net-mvc #asp.net-mvc-3
#asp.net-mvc #asp.net-mvc-3
Вопрос:
У меня есть экран редактирования продукта. Пользователь может выбрать поставщика для продукта. Для этого я показываю диалоговое окно jQueryUI, которое позволяет им просматривать и выбирать поставщика. Когда пользователь выбирает поставщика, я обновляю скрытый ввод VendorID на странице, который является частью модели моей страницы. Я также обновляю несколько разделов с подробной информацией о выбранном ими поставщике. Они предназначены только для отображения — для сохранения выбранного поставщика требуется только идентификатор.
Все это отлично работает, за исключением случаев, когда при обратной передаче возникает ошибка, и в этом случае я повторно отображаю тот же вид. ModelState заботится о сохранении всех полей моей формы (включая скрытый идентификатор поставщика). Однако мои divs с текстом поставщика (конечно) пусты, поскольку они не отправлены на сервер.
Сначала я пошел по пути создания скрытых полей для каждого из полей отображения моего поставщика и размещения их в модели. Тогда скрытые поля выдерживают обратную передачу, но это не решает проблему фактического повторного отображения текста на экране.
Три варианта, о которых я могу подумать::
- При обратной передаче, если есть ошибка, перейдите в базу данных, выберите поставщика, используя предоставленный идентификатор поставщика, и повторно заполните модель текстом, который я хочу отобразить.
- Используйте RenderAction и выполните действие, которое отображает сведения о выбранном поставщике.
- Используйте текстовые поля только для чтения вместо divs для отображения сведений о поставщике.
Ни один из них не кажется мне очень удовлетворительным. Я чувствую, что, возможно, мне не хватает очевидного решения. Есть ли какие-либо лучшие решения?
Ответ №1:
Я бы посоветовал вам не размещать дополнительную информацию о поставщике как часть главной страницы. Создайте функцию javascript showVendorInfo(). При вызове, если скрытый ввод VendorID имеет значение, он получает соответствующую информацию о поставщике через AJAX и отображает ее, используя метод действия AjaxGetVendorInfo. Вызовите эту функцию из двух мест:
- В document.ready()
- после выбора поставщика с помощью отображения jQueryUI.
Теперь это будет в методе действия. Вы могли бы, если ожидаете, что у ваших пользователей возникнут проблемы с задержкой, сделать следующее, чтобы избежать некоторых вызовов ajax: В представлении проверьте, знаете ли вы VendorID ; если да, вызовите Html.RenderAction вызовите тот же метод действия AjaxGetVendorInfo из представления.
Бонус к этому заключается в том, что он позволяет избежать того, что я считаю большим запретом: включать в вашу ViewModel как значения только для отображения, так и значения, привязанные к модели. Это создает очень запутанную ViewModel, особенно при наличии ошибок проверки. [Переход к мыльному ящику] Лучше всего, чтобы в вашей ViewModel были только свойства, предназначенные для привязки к модели, для вашего состояния. Поместите значения списка, дополнительную отображаемую информацию и т. Д. В ViewData или отобразите их через AJAX.
Комментарии:
1. Это звучит как чистое решение, в котором используется ajax для извлечения отображаемых данных. Немного связано с этим решением, если эти данные поступают из БД, вы можете использовать TempData на стороне сервера для кэширования результатов БД. Это также позволяет избежать дополнительного обращения к БД.
2. @Patrick Мне нравится ваш подход. Я попытался использовать RenderAction, как вы предложили при загрузке страницы, чтобы избежать вызова AJAX, но одна из проблем заключается в том, что при обратной передаче при добавлении нового продукта возникает ошибка, VendorID отсутствует в модели. Поэтому я не могу просто вызвать RenderAction, используя VendorID в моей модели, не обращаясь к ModelState, чтобы получить его, что кажется мне взломом. Есть мысли о том, как наилучшим образом справиться с этим случаем?
3. Я неправильно понимаю часть того, что вы делаете, просто не уверен, где. У вас есть свойство VendorID в ViewModel, верно? Итак, пользователь отправляет форму, и VendorID должен быть там в привязанной к модели ViewModel. В методе post action, прежде чем возвращать представление из-за ошибок modelstate, вы можете запросить у объекта ViewModel идентификатор поставщика, верно? Когда вы возвращаете представление при наличии ошибок проверки, передаете ли вы тот же объект ViewModel, который вы получили через modelbinding?
4. (продолжение) Ключ в том, чтобы не думать о ViewModel как о методе Get action и обо всем, что должно изначально отображаться в представлении. ViewModel существует для поддержания состояния в течение всего жизненного цикла. Там должен быть включен идентификатор поставщика, хотя он всегда остается пустым, когда кто-то переходит на страницу заново.
5. Если при добавлении возникает ошибка, я создаю новый экземпляр ViewModel. Я делаю это главным образом потому, что ViewModel необходимо повторно заполнить списки выбора. Но это также объясняет, почему у меня нет идентификатора поставщика. Продукт не был сохранен, поэтому, когда я воссоздаю ViewModel, идентификатор поставщика возвращается к значению по умолчанию. Я предполагаю, что это говорит о вашем предположении, что ViewModel имеет свойства только для привязки модели. Мне было бы интересно узнать больше о ваших рассуждениях по этому поводу. Я был в лагере, что все, что нужно для представления, должно быть в строго типизированной ViewModel, но меня можно убедить в обратном.