Le rendu HTML avec HtmlTextWriter n'est pas incroyablement intuitif à mon avis, mais si vous mettez en place des contrôles Web dans des formulaires Web, c'est ce que vous devez travailler. J'ai pensé qu'il serait peut-être possible de créer une interface fluide pour cela, qui ressemble un peu plus au HTML qu'elle produit. J'aimerais savoir ce que les gens pensent de la syntaxe que j'ai trouvée jusqu'à présent.Interface fluide pour le rendu 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();
}
« Tag », « Texte » et « EndTag » sont des méthodes d'extension pour la classe HtmlTextWriter qui retourne l'instance prend en sorte que les appels peuvent être chaînés. L'argument passé au lambda utilisé dans la surcharge utilisée par le premier appel à "Tag" est un "HtmlAttributeManager", qui est une simple classe qui enveloppe un HtmlTextWriter pour fournir un indexeur qui prend un HtmlTextWriterAttribute et une valeur de chaîne et retourne l'instance que les appels peuvent être enchaînés. J'ai aussi avoir des méthodes de cette classe pour les attributs les plus communs, tels que le « Nom », « classe » et « Id » afin que vous puissiez écrire le premier appel ci-dessus comme suit:
.Tag(HtmlTextWriterTag.Div, e => e.Id("id").Name("name").Class("class"))
Un petit exemple plus:
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);
}
Espérons que vous serez en mesure de « déchiffrer » ce HTML cette sorties de snippet, au moins c'est l'idée. S'il vous plaît donnez-moi des idées sur la façon dont la syntaxe peut être améliorée, peut-être de meilleurs noms de méthodes, peut-être une autre approche tous ensemble.
Edit: Je pensais que ce serait peut-être intéressant de voir ce que le même extrait ressemblerait sans l'utilisation de l'interface fluide, à titre de comparaison:
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: Je devrais probablement être un peu plus explicite en ce sens que l'un des objectifs est que cela devrait avoir le moins de frais possible, c'est pourquoi j'ai limité l'utilisation de lambdas. Aussi au début j'ai utilisé une classe qui représentait une balise pour que quelque chose de similaire à un arbre DOM ait été construit par la syntaxe avant le rendu, la syntaxe était cependant très similaire. J'ai abandonné cette solution pour la légère surcharge de mémoire qu'elle encourt. Il y a encore une partie de ceci présent dans l'utilisation de la classe HtmlAttributeManager, j'ai réfléchi à l'utilisation de méthodes d'extension pour l'ajout d'attributs, mais je ne peux pas utiliser la syntaxe indexer, aussi cela gonfle l'interface du HtmlTextWriter encore plus.
C'est cool. Je veux vous demander quelque chose avant de répondre ... pourquoi utilisez-vous la syntaxe de l'indexeur? Je ne vois aucun avantage à cela, et il est clair que cela est intrusif dans votre syntaxe. Je pense que vous avez probablement une bonne raison pour cela que je néglige. –
C'était le meilleur que je pouvais trouver, si je ne l'utilisais pas la syntaxe serait quelque chose comme "t => t.Attribute (clé, valeur) .Attribute (clé, valeur)" qui grandit assez grand. Avez-vous une autre idée de comment faire cela, les suggestions sont plus que bienvenues. –
Y avait-il une raison pour laquelle vous ne pouviez pas faire ceci: .Tag (HtmlTextWriterTag.Select) .Attribute ("Value", "1"). Attribut ("Title", "Sélectionne le numéro 1"). EndTag() –