net mvc htmlhelperextensions htmlhelper extensions custom asp asp.net-mvc razor tagbuilder

asp.net mvc - mvc - Nested TagBuilder-como TagBuilderTree-



htmlhelperextensions mvc (3)

El problema que tengo con TagBuilder para crear etiquetas es que parece muy poco sostenible. Por otro lado, AppendFormat de StringBuilder no solo hace que el código se pueda mantener, sino que también se ejecuta con buena eficacia.

He mejorado levemente el método # 1 de MattSlay. Utilicé solo una llamada al método AppendFormat de StringBuilder y utilicé el literal de cadena C # para definir el formato. Como resultado, el formato termina pareciéndose exactamente al resultado deseado y se ejecuta con eficiencia.

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());

¡Espero que esto ayude!

TagBuilder es una buena implementación para construir elementos HTML. Pero algunos elementos HTML pueden tener otros elementos (llamé como niños). No pude encontrar ninguna clase de clases de Mvc.

Pregunta; ¿Debería implementar algunas clases (TagBuilderTree y TagBuilderNode) que admitan etiquetas anidadas o me perdi algo?


OK, decidí hacer una pequeña prueba en mi propia base de código.

Comparé estos dos métodos para crear el mismo HTML final exacto:

  1. Generar manualmente el html usando un StringBuilder
  2. Usar múltiples TagBuilders y anidar el contenido

Generar manualmente el html usando un 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());

Usar múltiples TagBuilders y fusionar el contenido:

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());

Para mí, el # 1 es más fácil de leer y mucho más conciso, pero también puedo apreciar la estructura del # 2.


Puede construir los elementos secundarios en TagBuilders por separado y poner su HTML generado en el TagBuilder principal.

Aquí hay un ejemplo: A <select> con algunos <option> s (ejemplo desgranado para la concisión)

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(); }