Как сопоставить флажки с элементами модели MVC?
У меня есть MVC-представление
<%@ Page Language="C#" MasterPageFile="PathToMaster" Inherits="System.Web.Mvc.ViewPage<ModelData>" %>
и у меня есть форма с разметкой HTML для набора флажков:
<label for="MyCheckbox">Your choice</label>
<input type="checkbox" id="Option1" class="checkbox" name="MyCheckbox" value="Option one" />
<label for="Option1">Option one</label><br />
<input type="checkbox" id="Option2" class="checkbox" name="MyCheckbox" value="Option two" />
<label for="Option2">Option two</label><br />
и у меня есть пара управляющих действий
class MyController : Controller {
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult RequestStuff( ModelData data )
{
}
}
и это действие вызывается при отправке формы.
Как сопоставить флажки с элементами ModelData
(и какие элементы я должен добавить в ModelData
), чтобы при отправке формы data
хранилась информация о том, какие флажки отмечены?
Ответы
Ответ 1
ОК, этот будет для MVC3, но - сохранить изменения синтаксиса - должен работать и в MVC2. Подход, по сути, один и тот же.
Прежде всего, вы должны подготовить подходящую (View) модель
public class MyViewModel
{
[DisplayName("Option 1")]
public bool Option1 { get; set; }
[DisplayName("Option 2")]
public bool Option2 { get; set; }
}
Затем вы передаете эту модель в представление, которое вы показываете (контроллер):
public ActionResult EditMyForm()
{
var viewModel = new MyViewModel()
return View(viewModel);
}
с формой:
@model MyViewModel
@using( Html.BeginForm())
{
@Html.Label("Your choice")
@Html.LabelFor(model => model.Option1) // here the 'LabelFor' will show you the name you set with DisplayName attribute
@Html.CheckBoxFor(model => model.Option1)
@Html.LabelFor(model => model.Option2)
@Html.CheckBoxFor(model => model.Option2)
<p>
<input type="submit" value="Submit"/>
</p>
}
Теперь здесь помощники HTML (все CheckBoxFor
, LabelFor
, EditorFor
и т.д.) позволяют привязать данные к свойствам модели.
Теперь помните, что EditorFor
, когда свойство имеет тип bool
, также даст вам флажок в представлении.:)
И затем, когда вы отправляете контроллер, он автоматически привяжет значения:
[HttpPost]
public ActionResult EditMyForm(MyViewModel viewModel)
{
//And here the view model items will be set to true/false, depending what you checked.
}
Ответ 2
Сначала вы определяете SelectList
для параметров. Это будет использоваться для рендеринга флажков
public IList<SelectListItem> OptionsSelectList { get; set; }
Чем вы определяете модель, которая будет удерживать значение одного выбранного варианта после сообщения
public class ChooseOptionViewModel
{
public int OptionIdentifier { get; set; } //name or id
public bool HasBeenChosen { get; set; } //this is mapped to checkbox
}
Затем IList этих опций в ModelData
public IList<ChooseOptionViewModel> Options { get; set; }
И, наконец, представление
@for (int i = 0; i < Model.OptionsSelectList.Count(); i++)
{
<tr>
<td class="hidden">
@Html.Hidden("Options[" + i + "].OptionIdentifier", Model.OptionsSelectList[i].Value)
</td>
<td>
@Model.OptionsSelectList[i].Text
</td>
<td>
@Html.CheckBox("Options[" + i + "].HasBeenChosen", Model.Options != null && Model.Options.Any(x => x.OptionIdentifier.ToString().Equals(Model.OptionsSelectList[i].Value) && x.HasBeenChosen))
</td>
</tr>
}
После публикации вы просто проверяете Options.Where(x => x.HasBeenChosen)
Это полнофункционально, и это позволит вам повторно отображать представление при возникновении ошибок проверки и т.д. Это кажется немного сложным, но я не придумал лучшего решения, чем это.