Раскрывающийся список представления ASP.Net MVC не привязывается к модели после отправки (публикация) - PullRequest
4 голосов
/ 08 января 2010

У меня есть класс viewmodel для создания представления, который состоит из 2 свойств различных классов и списка элементов выбора (для выпадающего списка). Раскрывающийся список и поля для одного из классов всегда отображаются в представлении, но поля для 2-го класса отображаются только в том случае, если выбран конкретный параметр списка. (через загрузку jQuery и контроллер, который возвращает частичное представление, строго типизированный для 2-го класса)

Поля в представлении для второго класса - это обычные текстовые поля ввода = и раскрывающийся список.

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

Проблема в том, что если есть ошибка проверки, и я возвращаю представление с моделью (чтобы показать ошибки), тогда выпадающий список (тот, что для второго класса) пуст, и так как нет никакого способа выбрать Исходя из этого, отправка всегда будет иметь isValid = false: S

Это пример того, как я настраиваю вещи:

В настоящее время у меня есть модель вида, которая выглядит следующим образом:

public class ViewModel
{
   public GenericData genericData{get;set;}
   public SpecializedData specializedData {get;set;}
   public List<SelectListItem> types { get; set; }
}

public class GenericData
{
   public Type type {get;set;}
   public String name {get;set;}
   public String description{get;set;}
}
public class SpecializedData
{
   public String field{get;set;}
   public int foreignKey{get;set;}
   public List<SelectListItem> listOfForeignKeys{ get; set; }
}

Вид строго типизирован для ViewModel и настроен следующим образом:

<p>
   <label for="genericData.type"> Type:  </label>
        <%=Html.DropDownList("genericData.type",Model.types, "Choose a type") %>
</p>
<p>
    <label for="genericData.name"> Name:</label>
    <%: Html.TextBox("genericData.name")%>
    <%= Html.ValidationMessage("genericData.name", "*")%>
</p>
//Same thing for Description as for name

<div id="SpecializedFields">
           //This will display the specialized info it was already captured before.
           <% if (Model.SpecializedData!= null && Model.GenericData.Type == "Specialized")
           {
               Html.RenderPartial("SpecializedInfoView", Model.specializedData);
           } %>
</div>
<p>
     <input type="submit" value="Create" />
</p>

$(document).ready(function () {
        $("#CatalogItem_Type").change(function () {

            var typeVal = $("#GenericData_type").val();
            if (typeVal == "specialized") {
                $("#SpecializedFields").load("/MyController/SpecializedFields");
            }

контроллер будет делать что-то вроде этого

public ActionResult SpecializedFields()
{
     List<SelectListItem> foreignIds = getForeignIdsFromDataBase();
     SpecializedData model = new SpecializedData ();
     model.listOfForeignIds = foreignIds;
     return PartialView("SpecializedInfoView",model);
}

Наконец, SpecialezedInfoView является строго типизированным представлением для SpecializedData и аналогично общему, оно выглядит так:

<p>
   <label for="specializedData.foreignKey"> Key:  </label>    <%=Html.DropDownList("specializedData.foreignKey",Model.listOfForeignKeys, "Choose key") %>
</p>
<p>
    <label for="SpecializedData.field"> Field:</label>
    <%: Html.TextBox("specializedData.field")%>
    <%= Html.ValidationMessage("specializedData.field", "*")%>
</p>

Когда я нажимаю "Отправить", если это не специализированный элемент, я получаю нулевое значение для свойства specializedData, что нормально. Если это специализированный элемент, то он не будет нулевым, я получу все свойства из genericData и получу значения specializedData.field и specializedData.foreignKey, но specialized.listOfForeignKeys будет NULL, что означает, что если есть ошибка проверки и я возвращаю представление с текущей моделью, то все будет иметь ранее введенные значения, НО DropDownList со списком внешних ключей будет пустым , и сейчас нет способа выбрать идентификатор.

Я знаю, что мог бы проверить, не является ли specialData не равным NULL в методе, который получает сообщение, и заново сгенерировать список ключей и назначить его текущей модели (так как это единственные данные, которые отсутствуют) , но это означало бы необходимость делать дополнительные вызовы БД, а не информацию, находящуюся там с моделью!

Я знаю, что это длинный вопрос, но я хотел уточнить, как я настраиваю вещи, кто-нибудь знает, почему listOfForeignKeys не передается обратно модели после обратной передачи!?

Спасибо!

1 Ответ

4 голосов
/ 08 января 2010

Я понял ... дело в том, что значения DropDownLists НЕ отправляются обратно в модель, когда вы выполняете привязку ... однако, поскольку привязка автоматически вызывает конструктор модели представления, которой была List<SelectItemList> Types быть заполненным там на самом деле не из-за привязки. Второй список не встроен в конструктор, поэтому он имеет нулевое значение. Я добавил запрос, чтобы получить информацию для списка в конструкторе SpecializedData, и теперь он работает ..

Тем не менее, это отстой, что, когда пользователь нажимает на сообщение, в БД будет дополнительный вызов, и чаще, если будут ошибки проверки. Может быть, я попытаюсь создать кеш для хранения результатов запроса, но пока этого достаточно.

Спасибо!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...