Сохранять состояние динамического списка флажков в ASP.NET MVC

У меня есть класс под названием "PropertyFeature", который просто содержит PropertyFeatureID и описание. Это подходящая модель, созданная с помощью LINQ to SQL, сопоставленная с таблицей базы данных SQL Server. Пример экземпляра/строки:

PropertyFeatureID: 2
Description: "Swimming Pool"

Количество строк (PropertyFeatures) может, конечно, расти и сокращаться, и поэтому я хочу динамически отображать список флажков, чтобы пользователь мог выбрать любой из них. Я могу динамически визуализировать флажки достаточно легко, с чем-то вроде:

<%foreach (var Feature in (ViewData["Features"] as IEnumerable<MySolution.Models.PropertyFeature>)) { %>
<%=Html.CheckBox("Features", new { @id = Feature.PropertyFeatureID, @value = Feature.PropertyFeatureID })%><label for="Feature<%=Feature.PropertyFeatureID%>"><%=Feature.Description%></label>
<%}%>

Я указываю ID для каждого флажка и выставляю соответствующий ярлык, чтобы пользователь мог интуитивно щелкнуть метку и переключить флажок - это отлично работает.

Я установил имя "CheckBox" в "Функции", чтобы все флажки отображались с тем же именем, а MVC Model Binder слагал их в единый набор под названием "Особенности" при отправке формы. Это хорошо работает.

После отправки формы я использую проверенные значения и сохраняю их, поэтому мне нужны фактические целочисленные значения, поэтому я знаю, какой PropertyFeature выбран, а не просто куча логических и имен полей. Поэтому в идеале я хочу, чтобы это было массивом или коллекцией, с которой легко работать.

Я могу получить выбранные значения из моего метода контроллера при нажатии кнопки, потому что я указал параметр как int [].

Но проблема заключается в том, что она не поддерживает состояние. То есть, когда я нажимаю кнопку "Отправить" и перезагружается страница (снова отображается форма), я хочу, чтобы все динамические флажки сохраняли свой статус проверки (или нет). Все остальные поля, которые я создал с помощью Html.DropDownList и Html.TextBox, сохраняют свои состояния успешно без проблем на одной странице в той же форме.

Я потратил часы, читая все другие темы и статьи по подобным проблемам, и есть много разговоров об использовании ICollection и IDictionary для объединения вещей и включения логического значения для каждого элемента, чтобы он мог сохранить состояние флажка. Но я не понимаю 100%, как использовать это в контексте моего личного примера. Я бы хотел, чтобы решение было действительно простым и не нужно составлять страницы новых классов, чтобы поддерживать мое состояние флажка.

Каков самый чистый и правильный способ сделать это?

Ответ 1

Я начал работать после многократного разговора с различными подходами.

В представлении:

<%string[] PostFeatures = Request.Form.GetValues("Features");%>
<% foreach (var Feature in (ViewData["AllPropertyFeatures"] as 
                             IEnumerable<MySolution.Models.PropertyFeature>)) 
   { %>
    <input type="checkbox" name="Features"
        id="Feature<%=Feature.PropertyFeatureID.ToString()%>" 
        value="<%=Feature.PropertyFeatureID%>" 
        <%if(PostFeatures!=null) 
          {
             if(PostFeatures.Contains(Feature.PropertyFeatureID.ToString()))
             { 
                Response.Write("checked=\"checked\""); 
             }
          }
        %> />
    <label for="Feature<%=Feature.PropertyFeatureID%>">
          <%=Feature.Description%></label>   <%
   }  %>

В методе приемного контроллера:

public ActionResult SearchResults(int[] Features)

Этот метод имеет ряд преимуществ:

  • Позволяет щелкнуть ярлыки, чтобы переключать соответствующие флажки (юзабилити).
  • Позволяет методу Controller получать супер-аккуратный массив int, который ТОЛЬКО содержит выбранные ints, а не целую другую кучу элементов, которые были не выбраны или содержат false/null/blank/0 и т.д.
  • Сохраняет установленное флажком состояние, когда перезагрузка страницы содержит форму, то есть выбор пользователя сохраняется.
  • Никаких случайных/случайных типов = скрытых полей ввода, созданных по умолчанию ASP.Net MVC Html.CheckBox helper - я знаю, что он делает это по уважительной причине, но в этом случае я не требую их, поскольку я только хочу узнать, какие идентификаторы были выбраны, и для тех, кто находится в одном, аккуратном int [].
  • Никакие массы дополнительных серверов, раздутых классов, помощников и других счастливых беспорядков, необходимых для достижения такой простой вещи.

Я бы рекомендовал этот подход для тех, кто хочет получить самое чистое/безплатное решение для динамического списка флажков, где вам нужны идентификаторы, и вы просто хотите перейти к делу!

Ответ 2

Проблема заключается в том, что при рендеринге вашего списка флажков вы не устанавливаете ни один из них, как выбранный. Вам нужно будет установить int[] Features в ViewData, а затем в вашем цикле foreach, проверьте, находится ли идентификатор этой функции в массиве в ViewData.

что-то вроде:

<%=Html.CheckBox("Features", 
    ((int[])ViewData["SelectedFeatures"]).Contains(Feature.PropertyFeatureID),
    new { @id = Feature.PropertyFeatureID, @value = Feature.PropertyFeatureID })%

хотя я не тестировал его, поэтому он может быть не 100%.