Я пытаюсь создать html-помощник для создания списка флажков, которые будут иметь состояние проверки, сохраненное с помощью сеансов. Он работает по большей части, помня о состоянии флажка, когда вы проверяете и снимаете флажки с разных ящиков и нажимаете «Отправить». Однако, если у вас есть флажки, отмеченные и отправленные, и вы возвращаетесь и очищаете флажки и повторно отправляете (когда они ВСЕ очищены) - кажется, что хотите запомнить последние варианты. Вот то, что я написал ...Как я могу сохранить список флажков в MVC
[HomeController]
public ActionResult Index()
{
TestViewModel tvm = new TestViewModel();
return View(tvm);
}
[HttpPost]
public ActionResult Index(TestViewModel viewModel)
{
viewModel.SessionCommit();
return View(viewModel);
}
[Index View]
@model TestApp.Models.TestViewModel
@{
ViewBag.Title = "Index";
}
@using (Html.BeginForm())
{
<p>Checkboxes:</p>
@Html.CheckedListFor(x => x.SelectedItems, Model.CheckItems, Model.SelectedItems)
<input type="submit" name="Submit form" />
}
[TestViewModel]
// Simulate the checklist data source
public Dictionary<int, string> CheckItems
{
get
{
return new Dictionary<int, string>()
{
{1, "Item 1"},
{2, "Item 2"},
{3, "Item 3"},
{4, "Item 4"}
};
}
}
// Holds the checked list selections
public int[] SelectedItems { get; set; }
// Contructor
public TestViewModel()
{
SelectedItems = GetSessionIntArray("seld", new int[0]);
}
// Save selections to session
public void SessionCommit()
{
System.Web.HttpContext.Current.Session["seld"] = SelectedItems;
}
// Helper to get an int array from session
int[] GetSessionIntArray(string sessionVar, int[] defaultValue)
{
if (System.Web.HttpContext.Current.Session == null || System.Web.HttpContext.Current.Session[sessionVar] == null)
return defaultValue;
return (int[])System.Web.HttpContext.Current.Session[sessionVar];
}
[HTML-помощник]
public static MvcHtmlString CheckedList(this HtmlHelper htmlHelper, string PropertyName, Dictionary<int, string> ListItems, int[] SelectedItemArray)
{
StringBuilder result = new StringBuilder();
foreach(var item in ListItems)
{
result.Append(@"<label>");
var builder = new TagBuilder("input");
builder.Attributes["type"] = "checkbox";
builder.Attributes["name"] = PropertyName;
builder.Attributes["id"] = PropertyName;
builder.Attributes["value"] = item.Key.ToString();
builder.Attributes["data-val"] = item.Key.ToString();
if (SelectedItemArray.Contains(item.Key))
builder.Attributes["checked"] = "checked";
result.Append(builder.ToString(TagRenderMode.SelfClosing));
result.AppendLine(string.Format(" {0}</label>", item.Value));
}
return MvcHtmlString.Create(result.ToString());
}
public static MvcHtmlString CheckedListFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper, Expression<Func<TModel, TProperty>> expression, Dictionary<int, string> ListItems, int[] SelectedItemArray)
{
var name = ExpressionHelper.GetExpressionText(expression);
var metadata = ModelMetadata.FromLambdaExpression(expression, htmlHelper.ViewData);
return CheckedList(htmlHelper, name, ListItems, SelectedItemArray);
}
Я прочитал this SO question, и я думаю, что это может быть связано с моделью связующего, не зная, когда нет галочки проверяются, но даже если я прошел через это и различные другие должности - я больше не продвигаюсь вперед.
В одном сообщении я увидел, что скрытое поле часто используется в сочетании с флажком для передачи «ложного» состояния флажка, но я не мог заставить его работать с несколькими флажками, отправляя обратно в одно свойство ,
Может ли кто-нибудь пролить свет на это?
EDITED: включить demonstration project Я выделил в этом сообщении. Надеюсь, это поможет кому-то помочь мне!
Отличный отклик и почти понял. Не могли бы вы уточнить 3 и 4 в своем ответе. Я понимаю (в 4), что я не использую выражение, но как вы получаете значение из выражения в виде массива int? Я слышу вашу рекомендацию, однако я хочу научиться делать это самостоятельно, вместо того, чтобы полагаться на пакеты/черные ящики. Только начал MVC пару месяцев назад, так что все еще работаю над этим. – Simon
Пункт 3: обратитесь к [private static MvcHtmlString InputHelper (...)] (https://aspnetwebstack.codeplex.com/SourceControl/latest#src/System.Web.Mvc/Html/InputExtensions.cs), чтобы узнать, как хелперы обычно устанавливают атрибут 'value' и порядок проверки. И чтобы понять, почему сначала проверяется «ModelState», обратитесь к второй части [этого ответа] (http://stackoverflow.com/questions/26654862/textboxfor-displaying-initial-value-not-the-value-updated-from -code/26664111 # 26664111) –
Пункт 4: Свойство 'Model'' ModelMetadata содержит модель, поэтому вы можете использовать 'return CheckedList (htmlHelper, name, ListItems, metadata.Model);' и удалить последний параметр –