Вложенный TagBuilder-как TagBuilderTree- - PullRequest
26 голосов
/ 10 февраля 2011

TagBuilder - хорошая реализация для построения HTML-элементов. Но некоторые элементы HTML могут иметь другие элементы (я их назвал как дети). Я не мог найти ни одного класса из классов Mvc.

Вопрос; Должен ли я реализовать несколько классов (TagBuilderTree и TagBuilderNode), которые поддерживают вложенные теги, или я что-то пропустил?

Ответы [ 3 ]

45 голосов
/ 10 февраля 2011

Вы можете создавать дочерние элементы в отдельных TagBuilder и помещать их сгенерированный HTML в родительский TagBuilder.

Вот пример: A <select> с некоторыми <option> s (пример обезжирен для краткости)

TagBuilder select = new TagBuilder("select");  

foreach (var language in languages) // never ye mind about languages
{
    TagBuilder option = new TagBuilder("option");
    option.MergeAttribute("value", language.ID.ToString());

    if (language.IsCurrent)
    {
        option.MergeAttribute("selected", "selected");
    }

    option.InnerHtml = language.Description;
    // And now, the money-code:
    select.InnerHtml += option.ToString();
}
5 голосов
/ 13 декабря 2012

ОК, я решил сделать небольшой тест в своей собственной кодовой базе.

Я сравнил эти два метода для создания одного и того же точного окончательного HTML:

  1. Генерация html вручную с помощью StringBuilder
  2. Использование нескольких TagBuilders и вложение содержимого

Генерация html вручную с помощью StringBuilder:


    var sb = new StringBuilder();
    sb.AppendLine("<div class='control-group'>");
    sb.AppendFormat(" <label class='control-label' for='{0}_{1}'>{2}</label>", propObj.ModelType, propObj.ModelProperty, propObj.LabelCaption);
    sb.AppendLine("  <div class='controls'>");
    sb.AppendFormat("    <input id='{0}_{1}' name='{0}[{1}]' value='{2}' />", propObj.ModelType, propObj.ModelProperty, propObj.PropertyValue);
    sb.AppendLine("  </div>");
    sb.AppendLine("</div>");

    return new HtmlString(sb.ToString());

Использование нескольких TagBuilders и объединение контента:


    TagBuilder controlGroup = new TagBuilder("div");
    controlGroup.AddCssClass("control-group");

    TagBuilder label = new TagBuilder("label");
    label.AddCssClass("control-label");
    label.InnerHtml = propObj.LabelCaption;

    TagBuilder controls = new TagBuilder("div"); 

    TagBuilder input = new TagBuilder("input");
    input.Attributes["id"] = propObj.ModelType + "_" + propObj.ModelProperty;
    input.Attributes["name"] = propObj.ModelType + "[" + propObj.ModelProperty + "]";
    input.Attributes["value"] = propObj.PropertyValue;

    controls.InnerHtml += input;

    controlGroup.InnerHtml += label;
    controlGroup.InnerHtml += controls;

    return new HtmlString(controlGroup.ToString());

Для меня # 1 легче читать и гораздо лаконичнее, но я также могу оценить структуру # 2.

0 голосов
/ 13 августа 2013

Проблема с TagBuilder, с которой я сталкиваюсь при создании тегов, заключается в том, что она выглядит крайне необслуживаемой.С другой стороны, AppendFormat StringBuilder не только делает код обслуживаемым, но и работает с хорошей эффективностью.

Я немного улучшил метод MattSlay # 1.Я использовал только один вызов метода AppendFormat StringBuilder и использовал строковый литерал C # для определения формата.В результате формат в конечном итоге выглядит точно так же, как желаемый результат, и работает с эффективностью.

var sb = new StringBuilder();
    sb.AppendFormat(
     @"<div class='control-group'>
          <label class='control-label' for='{0}_{1}'>{2}</label>
          <div class='controls'>
             <input id='{0}_{1}' name='{0}[{1}]' value='{3}' />
          </div>
      </div>",
      propObj.ModelType,
      propObj.ModelProperty,
      propObj.LabelCaption,
      propObj.PropertyValue);

    return new HtmlString(sb.ToString());

Надеюсь, это поможет!

...