Книга: ASP.NET MVC Framework

Использование дополнительных слоев абстракции

Использование дополнительных слоев абстракции

Достигнуть большего контроля над логикой и разметкой можно за счет использования дополнительной абстракции над созданием самой разметки, вынесением отдельных методов, генерирующих повторяющие элементы, и созданием тегов с помощью специального класса TagBuilder. В WebForms при создании контролов (Custom Controls) используется похожий подход.

TagBuilder активно применяется в расширениях, входящих в саму сборку System.Web.Mvc, в чем можно убедиться, посмотрев, например, на исходный код System.Web.MVC.SelectExtensions.

В листинге 5.13 приведен код, использующий больше абстракции, нежели предыдущие. Также в листинге 5.13 продемонстрирована простая концепция по восстановлению значений после отправки данных на сервер (метод Getvalue, выполняющий поиск в коллекции viewData, затем в параметрах запроса).

Листинг 5.13. Реализация метода DatePicker с дополнительными слоями абстракции

public static class DataPickerHelper
{
  private static string DAY_PREFIX = "day_";
  private static string MONTH_PREFIX = "month_";
  private static string YEAR_PREFIX = "year_";
  private static string ListItemToOption(SelectListItem item)
  {
    TagBuilder builder = new TagBuilder("option")
    {
      InnerHtml = HttpUtility.HtmlEncode(item.Text)
    };
    if (item.value != null)
      builder.Attributes["value"] = item.Value;
    if (item.Selected)
      builder.Attributes["selected"] = "selected";
    return builder.ToString(TagRenderMode.Normal);
}
private static string SelectList(string id,
                             List<SelectListItem> items)
{
  StringBuilder listItemBuilder = new StringBuilder();
  foreach (var item in items)
  {
    listItemBuilder.AppendLine(ListItemToOption(item));
  }
  TagBuilder tagBuilder = new TagBuilder("select")
  {
    InnerHtml = listItemBuilder.ToString()
  };
  tagBuilder.Attributes.Add("id", id);
  tagBuilder.Attributes.Add("name", id);
  return tagBuilder.ToString(TagRenderMode.Normal);
}
  public static string DatePicker(this HtmlHelper html, string id)
  {
    return DatePicker(html, id, String.Empty);
  }
  public static string DatePicker(this HtmlHelper html,
                                string id, string text)
  {
    // buffer
    StringBuilder sb = new StringBuilder();
    // generate days
    List<SelectListItem> days = new List<SelectListItem>();
    string dayValue = GetValue(html, DAY_PREFIX + id);
    for (int i = 0; i <= 31; i++)
    {
      days.Add(new SelectListItem
      {
        Text = (i == 0) ? String.Empty : i.ToString(),
        Value = i.ToString(),
        Selected = (dayValue == i.ToString())
      });
    }
    sb.AppendLine(SelectList(DAY_PREFIX + id, days));
    // generate months
    List<SelectListItem> months = new List<SelectListItem>();
    string monthValue = GetValue(html, MONTH_PREFIX + id);
    for (int i = 0; i <= 12; i++)
    {
      months.Add(new SelectListItem
      {
        Text = (i == 0) ? String.Empty :
           DateTimeFormatInfo.CurrentInfo.MonthNames[i — 1],
        Value = i.ToString(),
        Selected = (monthValue == i.ToString())
      });
    }
    sb.AppendLine(SelectList(MONTH_PREFIX + id, months));
    // generate years
    List<SelectListItem> years = new List<SelectListItem>();
    string yearValue = GetValue(html, YEAR_PREFIX + id);
    for (int i = 1900; i <= DateTime.Now.Year; i++)
    {
      years.Add(new SelectListItem
      {
        Text = (i == 1900) ? String.Empty : i.ToString(),
           Value = i.ToString(),
        Selected = (yearValue == i.ToString())
      });
    }
    sb.AppendLine(SelectList(YEAR_PREFIX + id, years));
    // parent tag
    if (!String.IsNullOrEmpty(text))
    {
      TagBuilder div = new TagBuilder("div");
      div.Attributes.Add("id", id);
      div.InnerHtml = text + sb.ToString();
      sb = new StringBuilder(
              div.ToString(TagRenderMode.Normal));
    }
    return sb.ToString();
  }
  private static string GetValue(HtmlHelper html, string id)
  {
    object o = null;
    if (html.ViewData != null)
      o = html.ViewData.Eval(id);
    if (o == null)
      o = html.ViewContext.RequestContext.HttpContext.Request.Params[id];
    return (o == null) ? String.Empty : o.ToString();
  }
}

Оглавление книги


Генерация: 1.171. Запросов К БД/Cache: 3 / 1
поделиться
Вверх Вниз