Несколько флажков в бритве (с помощью foreach)
У меня есть проблема, и я не могу найти решение. Я использую Razor, и это мой класс VieModel.
public class GroupToExport
{
public GroupToExport()
{
ToExport = false;
}
[DisplayName("Export")]
public bool ToExport { get; set; }
public Group Group { get; set; }
}
public class GroupsToExport
{
public GroupsToExport()
{
//refill list
}
public List<GroupToExport> ExportingGroups { get; set; }
}
Посмотреть:
@using (Html.BeginForm("Export", "ElmahGroup", FormMethod.Post, new { id = "toExportForm" }))
{
//some divs
<input type="submit" id="js-export-submit" value="Export" />
@foreach (var item in Model.ExportingGroups)
{
<tr>
<td class="js-export-checkbox">
@Html.CheckBoxFor(modelItem => item.ToExport)
</td>
</tr>
}
//some divs
}
контроллер:
public ActionResult Export(GroupsToExport model)
{
var groupsToExport = model.ExportingGroups.Where(x => x.ToExport).Select(x => x);
throw new System.NotImplementedException();
}
После отправки "ToExport" в Controller каждая группа всегда имеет значение "false". Даже если все группы проверены.
Кто-нибудь может мне помочь? Что я делаю не так?
3 ответа
Вы не можете использовать foreach
цикл для создания элементов управления для коллекции. HTML, который вы генерируете для каждого флажка (и для соответствующего скрытого ввода), <input type="checkbox" name="item.ToExport" .../>
, Ваша модель не содержит свойство с именем item
,
Использовать for
петля
@for(int i = 0; i < Model.ExportingGroups.Count; i++)
{
<tr>
<td class="js-export-checkbox">
@Html.CheckBoxFor(m => m.ExportingGroups[i].ToExport)
</td>
</tr>
}
Теперь ваш HTML будет
<input name="ExportingGroups[0].ToExport" .../>
<input name="ExportingGroups[1].ToExport" .../>
и т.д., который будет правильно связываться с вашей моделью
редактировать
В качестве альтернативы вы можете использовать пользовательские EditorTemplate
для typeof GroupToExport
, Создать частичное представление /Views/Shared/EditorTemplates/GroupToExport.cshtml
@model yourAssembly.GroupToExport
<tr>
<td class="js-export-checkbox">
@Html.CheckBoxFor(m => m.ToExport)
</td>
</tr>
А потом на главном экране
@Html.EditorFor(m => m.ExportingGroups)
EditorFor()
Метод сгенерирует правильный HTML для каждого элемента в вашей коллекции на основе шаблона.
Вы используете неверный синтаксис для сопоставления значений обратно при их публикации, поскольку проверенное значение флажка по умолчанию инициализируется как ложное, поэтому всегда ложно, используйте sysntax
@for(int i = 0; i < Model.ExportingGroups.Count(); i++)
{
<tr>
<td class="js-export-checkbox">
@Html.CheckBoxFor(modelItem => Model.ExportingGroups[i].ToExport)
</td>
</tr>
}
//some divs
Это должно отобразить все значения, которые вы ищете.
Я обнаружил, что это работает намного лучше: оставьте цикл foreach как есть (не используйте счетчик)
@foreach (var item in Model.GroupToExport)
{
Затем используйте этот формат Razor для отображения флажка
@Html.CheckBox("Active", @item.ToExport)
Прост в использовании и не заставляет вас менять типичный цикл foreach.