Я создаю собственный помощник Html для обработки списка флажков. Я знаю, что в Интернете есть масса информации по этой теме, но я мало что видел, пытаясь сгенерировать HTML, как показано ниже.
Желаемый визуализированный HTML
<ul>
<li>
<label>
<input type="checkbox" name="Genres" value="SF" />
Science Fiction
</label>
</li>
<li>
<label>
<input type="checkbox" name="Genres" value="HR" />
Horror
</label>
</li>
<!-- more genres -->
</ul>
Я использую отдельные флажки значения, а не только логические значения, потому что хочу воспользоваться преимуществом того факта, что при публикации формы я получаю список выбранных значений, разделенных запятыми. . Например, если бы были выбраны одновременно Sci-Fi и Horror, я бы получил "SF,HR"
.
Посмотреть модель
public class MovieViewModel
{
public string Name { get;set; }
public string Year { get;set; }
public IEnumerable<string> Genres { get;set; }
public IEnumerable<SelectListItem> GenreOptions { get;set; }
}
Вид
На мой взгляд, я хотел бы в основном это сделать:
@Html.EditorFor(model => model.Name)
@Html.EditorFor(model => model.Year)
@Html.CheckBoxListFor(model => model.Genres, Model.GenreOptions)
Пользовательский помощник по HTML
Итак, я начал создавать собственный помощник Html, но у меня нет большого опыта работы с ними, и здесь мне нужна помощь:
public static MvcHtmlString CheckboxListFor<TModel, TProperty>(this HtmlHelper<TModel> htmlHelper,
Expression<Func<TModel, TProperty>> expression,
IEnumerable<SelectListItem> items)
{
if (items == null) return null;
var itemsList = items.ToList();
if (!itemsList.Any()) return null;
// How do I get "Genres" name from the passed expression from viewmodel, without passing the hardcoded string "genres"?
var checkboxGroupName = expression.what????
var sb = new StringBuilder();
sb.Append("<ul>");
foreach (var item in itemsList)
{
var checkbox = $"<input type=\"checkbox\" name=\"{checkboxGroupName}\" value=\"{item.Value}\" />";
sb.Append($"<li class=\"checkbox\"><label>{checkbox} {HttpUtility.HtmlEncode(item.Text)}</label></li>");
}
sb.Append("</ul>");
return MvcHtmlString.Create(sb.ToString());
}
Как вы можете видеть в комментарии выше, я не знаю, как динамически назначать имя свойства модели представления «Жанры» атрибуту name
флажков без жесткого его кодирования. Как мне получить это из model => model.Genres
выражения?
ExpressionHelper.GetExpressionText(expression)
работал хорошо, как и ответ @Ehsan Sajjad ниже! Спасибо! Однако как насчет сценариев вложенных моделей просмотра? Как мне получить что-то вроде<input name="Movie.Genres" />
? И да, вы правы насчет ранее существовавшего состояния флажков. Думаю, я еще не зашел так далеко. Есть указатели? - person Jiveman   schedule 27.01.2017@CheckboxListFor(m => m.ComplexProperty.SomeProperty, ....)
вернет"SomeProperty"
. Вам нужно использовать код из моего первого комментария, который даст"ComplexProperty.SomePropery"
- person   schedule 27.01.2017@Html.EditorFor(m => m.Movie)
, где Movie имеет типMovieViewModel
, в котором есть жанры, как описано в моем OP. Не уверен, хорошо ли я описываю все дело с вложением. И да, я полагаю, мне также нужно будет изучить валидацию. С нетерпением жду вашего подхода к этому вопросу! - person Jiveman   schedule 27.01.2017MovieViewModel
, ваше выражение должно бытьm=> m.Genres
. Если у вас есть родительская модель представления, содержащая свойствоMovieViewModel Movies
, тогда выражение будетm => m.Movies.Genres
(в этом случаеExpressionHelper.GetExpressionText(expression)
будет генерироватьname="Movies.Genres"
(ноmetadata.PropertyName
не будет) - person   schedule 27.01.2017@Html.EditorFor(m => m.Movie)
? В этом случае я бы не хотел помещать жанры непосредственно в родительский вид, верно, но полагался бы на шаблон редактора MovieViewModel для его рендеринга. - person Jiveman   schedule 27.01.2017