Сохранять состояние динамического списка флажков в 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%.