用我的意见来渲染HTML与HtmlTextWriter并不是非常直观,但是如果你正在web窗体中实现web控件,那么你必须使用它。我认为有可能为此创建一个流畅的接口,它的读取更像是它输出的HTML。我想知道人们到底想到了什么语法。流畅的用于渲染的界面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();
}
“标签”,“文本”和“结束标记”是返回它需要在这样的呼叫可以链接实例HtmlTextWriter类的扩展方法。传递给用于第一次调用“标记”的重载的lambda的参数是一个“HtmlAttributeManager”,它是一个简单的类,它封装了一个HtmlTextWriter以提供一个索引器,它接受一个HtmlTextWriterAttribute和一个字符串值并返回实例该呼叫可以被链接。我也有这个类最常见的属性的方法,如“名称”,“类”和“ID”,让你可以写第一次调用上面如下:
.Tag(HtmlTextWriterTag.Div, e => e.Id("id").Name("name").Class("class"))
再长一点例子:
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);
}
希望你能够“破译”这段代码输出的HTML,至少这是主意。
请给我任何想法,如何可以改善语法,也许更好的方法名称,也许其他一些方法一起。
编辑: 我想这可能是有趣的,看看同样的片段将是什么样子,而无需使用流畅的界面,进行比较:
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();
}
编辑: 我也许应该多一点明确的一点是,它应该承担尽可能少的开销,这就是为什么我限制使用lambda表达式。此外,起初我使用了一个代表标签的类,以便在渲染之前通过语法构建类似于DOM树的东西,但语法非常相似。我放弃了这个解决方案,因为它产生了轻微的内存开销。在使用HtmlAttributeManager类时仍然存在一些这样的情况,我一直在考虑使用扩展方法来附加属性,但是我不能使用索引器语法,也扩展了HtmlTextWriter的接口更。
这是很酷的。在我回复之前,我想问你一些问题...你为什么使用索引器语法?我没有看到它的好处,显然它侵入你的语法。我想你可能有一个很好的理由,我可以忽略它。 – 2009-03-29 06:45:23
这是最好的我可以拿出来,如果我不使用它的语法会像“t => t.Attribute(key,value).Attribute(key,value)”那样增长很大。对于如何做到这一点,你有另一个想法,建议是非常值得欢迎的。 – 2009-03-30 07:06:39
是否有这样的原因:.Tag(HtmlTextWriterTag.Select).Attribute(“Value”,“1”)。Attribute(“Title”,“Selects the number 1”)。EndTag() – 2009-04-01 05:11:56