representación HTML con el HtmlTextWriter no es muy intuitivo en mi opinión, pero si va a implementar controles web en formularios web que es lo que tiene que trabajar. Pensé que sería posible crear una interfaz fluida para esto que se parece un poco más al HTML que genera. Me gustaría saber qué opina la gente sobre la sintaxis que he presentado hasta ahora.interfaz fluida para la representación HTML
public void Render(HtmlTextWriter writer)
{
writer
.Tag(HtmlTextWriterTag.Div, e => e[HtmlTextWriterAttribute.Id, "id"][HtmlTextWriterAttribute.Name,"name"][HtmlTextWriterAttribute.Class,"class"])
.Tag(HtmlTextWriterTag.Span)
.Text("Lorem")
.EndTag()
.Tag(HtmlTextWriterTag.Span)
.Text("ipsum")
.EndTag()
.EndTag();
}
"Etiqueta", "texto" y "etiqueta de cierre" son los métodos de extensión para la clase HtmlTextWriter que devuelve la instancia en que se necesita para que las llamadas se pueden encadenar. El argumento que se pasa a la lambda utilizado en la sobrecarga utilizado por la primera llamada a la "etiqueta" es un "HtmlAttributeManager", que es la clase simple que envuelve una HtmlTextWriter para proporcionar un indexador que toma un HtmlTextWriterAttribute y un valor de cadena y devuelve la instancia para que las llamadas se pueden encadenar También tengo métodos en esta clase para los atributos más comunes, tales como "Nombre", "clase" y "ID" de manera que se podría escribir la primera llamada por encima de la siguiente manera:
.Tag(HtmlTextWriterTag.Div, e => e.Id("id").Name("name").Class("class"))
Un pequeño ejemplo más:
public void Render(HtmlTextWriter writer)
{
writer
.Tag(HtmlTextWriterTag.Div, a => a.Class("someClass", "someOtherClass"))
.Tag(HtmlTextWriterTag.H1).Text("Lorem").EndTag()
.Tag(HtmlTextWriterTag.Select, t => t.Id("fooSelect").Name("fooSelect").Class("selectClass"))
.Tag(HtmlTextWriterTag.Option, t => t[HtmlTextWriterAttribute.Value, "1"][HtmlTextWriterAttribute.Title, "Selects the number 1."])
.Text("1")
.EndTag(HtmlTextWriterTag.Option)
.Tag(HtmlTextWriterTag.Option, t => t[HtmlTextWriterAttribute.Value, "2"][HtmlTextWriterAttribute.Title, "Selects the number 2."])
.Text("2")
.EndTag(HtmlTextWriterTag.Option)
.Tag(HtmlTextWriterTag.Option, t => t[HtmlTextWriterAttribute.Value, "3"][HtmlTextWriterAttribute.Title, "Selects the number 3."])
.Text("3")
.EndTag(HtmlTextWriterTag.Option)
.EndTag(HtmlTextWriterTag.Select)
.EndTag(HtmlTextWriterTag.Div);
}
Esperamos que pueda ser capaz de "descifrar" lo HTML salidas de este fragmento, al menos esa es la idea.
Por favor, dame alguna idea de cómo la sintaxis puede ser mejorado, tal vez mejores nombres de métodos, tal vez algún otro enfoque todos juntos.
Editar: pensé que podría ser interesante ver lo que el mismo fragmento vería sin el uso de la interfaz fluida, para la comparación:
public void RenderUsingHtmlTextWriterStandardMethods(HtmlTextWriter writer)
{
writer.AddAttribute(HtmlTextWriterAttribute.Class, "someClass someOtherClass");
writer.RenderBeginTag(HtmlTextWriterTag.Div);
writer.RenderBeginTag(HtmlTextWriterTag.H1);
writer.Write("Lorem");
writer.RenderEndTag();
writer.AddAttribute(HtmlTextWriterAttribute.Id, "fooSelect");
writer.AddAttribute(HtmlTextWriterAttribute.Name, "fooSelect");
writer.AddAttribute(HtmlTextWriterAttribute.Class, "selectClass");
writer.RenderBeginTag(HtmlTextWriterTag.Select);
writer.AddAttribute(HtmlTextWriterAttribute.Value, "1");
writer.AddAttribute(HtmlTextWriterAttribute.Title, "Selects the number 1.");
writer.RenderBeginTag(HtmlTextWriterTag.Option);
writer.Write("1");
writer.RenderEndTag();
writer.AddAttribute(HtmlTextWriterAttribute.Value, "2");
writer.AddAttribute(HtmlTextWriterAttribute.Title, "Selects the number 2.");
writer.RenderBeginTag(HtmlTextWriterTag.Option);
writer.Write("2");
writer.RenderEndTag();
writer.AddAttribute(HtmlTextWriterAttribute.Value, "3");
writer.AddAttribute(HtmlTextWriterAttribute.Title, "Selects the number 3.");
writer.RenderBeginTag(HtmlTextWriterTag.Option);
writer.Write("3");
writer.RenderEndTag();
writer.RenderEndTag();
writer.RenderEndTag();
}
EDIT: probablemente debería ser un poco más explícito en que uno de los objetivos con esto es que debe incurrir en la menor sobrecarga posible, esta es la razón por la que he limitado el uso de lambdas. También al principio usé una clase que representaba una etiqueta para que la sintaxis construyera algo similar a un árbol DOM antes de la representación, aunque la sintaxis era muy similar. Abandoné esta solución por la leve sobrecarga de memoria en la que incurre. Todavía hay algo de esta presente en el uso de la clase HtmlAttributeManager, he estado pensando acerca del uso de los métodos de extensión para la Anexión de atributos también, pero el que no puedo usar el indexador-sintaxis, también se hincha la interfaz de la HtmlTextWriter aún más.
Esto es muy bueno. Quiero preguntarte algo antes de responder ... ¿por qué estás usando la sintaxis del indexador? No veo un beneficio para él, y claramente es intrusivo en su sintaxis. Creo que probablemente tengas una buena razón para eso que estoy pasando por alto. –
Era lo mejor que se me ocurría, si no lo usaba, la sintaxis sería algo así como "t => t.Attribute (clave, valor) .Atributo (clave, valor)" que crece bastante. ¿Tiene otra idea de cómo hacer esto? Las sugerencias son más que bienvenidas. –
¿Hubo alguna razón por la que no pudo hacer esto: .Tag (HtmlTextWriterTag.Select) .Attribute ("Value", "1"). Attribute ("Title", "Selecciona el número 1"). EndTag() –