C # MVC Html помощник + выражения + убрать уродливость - PullRequest
3 голосов
/ 08 июля 2011

Я пытаюсь создать выпадающий список из IList со следующим синтаксисом:

@Html.DropDowntListFor(Model.VisitingAddresses, vistingAddress => vistingAddress.Id, vistingAddress => vistingAddress.Name)

Это работает со следующим кодом:

public static IHtmlString DropDowntListFor
        <TModel>(this HtmlHelper htmlHelper, IList<TModel> list, Expression<Func<TModel, string>> value, Expression<Func<TModel, string>> text)
    {
        var dropdownName = value.Parameters.First().Name;

        var selectedListItem = new List<SelectListItem>();

        var values = list.AsQueryable().Select(value).ToList();
        var texts = list.AsQueryable().Select(text).ToList();

        int i;
        for (i = 0; i < values.Count; i++)
        {
            selectedListItem.Add(new SelectListItem
                                     {
                                        Value = values[i],
                                        Text = texts[i]
                                     });
        }

        return htmlHelper.DropDownList(dropdownName, selectedListItem);
    }

Но, как вы можете видеть, приведенный выше код (в htmlhelper) действительно очень уродлив, есть ли кто-то, кто знает более красивый способ (в коде) для html helper?

Заранее спасибо.

Ответы [ 2 ]

4 голосов
/ 08 июля 2011

Вы после чего-то вроде этого?

public static IHtmlString DropDowntListFor<TModel>
    (this HtmlHelper htmlHelper, IList<TModel> list, 
     Expression<Func<TModel, string>> valueSelector, 
     Expression<Func<TModel, string>> textSelector)
{
    var dropdownName = valueSelector.Parameters.First().Name;

    Func<TModel, string> compiledValueSelector = valueSelector.Compile();
    Func<TModel, string> compiledTextSelector = textSelector.Compile();

    var selectedListItem = list.Select(x => new SelectListItem {
                                           Value = compiledValueSelector(x),
                                           Text = compiledTextSelector(x) })
                               .ToList();

    return htmlHelper.DropDownList(dropdownName, selectedListItem);
}

Обратите внимание, что если вам не нужен текстовый селектор в качестве дерева выражений, вы можете немного упростить его:

public static IHtmlString DropDowntListFor<TModel>
    (this HtmlHelper htmlHelper, IList<TModel> list, 
     Expression<Func<TModel, string>> valueSelectorExpression, 
     Func<TModel, string> textSelector)
{
    var dropdownName = valueSelector.Parameters.First().Name;

    var valueSelector = valueSelectorExpression.Compile();

    var selectedListItem = list.Select(x => new SelectListItem {
                                           Value = valueSelector(x),
                                           Text = textSelector(x) })
                               .ToList();

    return htmlHelper.DropDownList(dropdownName, selectedListItem);
}
0 голосов
/ 08 июля 2011

Как насчет следующего:

@Html.DropDowntListForVisitingAddress(x => x.Id, x => x.Name)

и затем, поскольку ваше представление уже строго типизировано для некоторой модели, HtmlHelper уже строго типизировано => используйте это для извлечения модели:

public static IHtmlString DropDowntListForVisitingAddress(
    this HtmlHelper<MyViewModel> html,
    Func<VisitingAddress, string> value,
    Func<VisitingAddress, string> text
)
{
    MyViewModel model = html.ViewData.Model;
    var values = model.VisitingAddresses.Select(x => new SelectListItem
    {
        Value = value(x),
        Text = text(x)
    });
    var selectList = new SelectList(values, "Value", "Text");
    return html.DropDownListFor(
        x => x.SelectedAddress,
        selectList
    );
}
...