微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

.net – 用于呈现HTML的流畅界面

在我看来,使用 HtmlTextWriter渲染HTML并不是非常直观,但是如果您在Web表单中实现Web控件,那么您必须使用它.我认为可能为此创建一个流畅的界面,读取的内容更像是它输出的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”,“Text”和“EndTag”是HtmlTextWriter类的扩展方法,它返回所需的实例,以便可以链接调用.传递给在第一次调用“Tag”时使用的重载中使用的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,"2"][HtmlTextWriterattribute.Title,"Selects the number 2."])
                    .Text("2")
                .EndTag(HtmlTextWriterTag.Option)
                .Tag(HtmlTextWriterTag.Option,"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();
}

编辑:
我可能会更明确一点,因为这样做的目的之一是尽可能少的开销,这就是为什么我限制了使用lambdas的原因.另外起初我使用一个代表一个标签的类,以便在渲染之前通过语法构建与DOM树类似的东西,但语法非常相似.我放弃了这个解决方案,造成轻微的内存开销.在使用HtmlAttributeManager类中还有一些存在,我一直在考虑使用扩展方法来附加属性,但是我不能使用索引器语法,它也使HtmlTextWriter的接口膨胀更.

解决方法

有两个问题我看到:

>重复使用Tag(Tagname,…).为什么不为每个标签名称提供扩展方法?诚然,这使得界面膨胀,并且写得很多(=>代码生成!).
>编译器/ IDE不能帮助你.特别地,它不检查缩进(当您自动缩进时甚至会破坏它).

这两个问题也许可以通过使用Lambda方法解决

writer.Write(body => new Tag[] {
    new Tag(h1 => "Hello,world!"),new Tag(p => "Indeed. What a lovely day.",new Attr[] {
        new Attr("style","color: red")
    })
});

这只是一个基本的方法. API肯定需要更多的工作.特别地,由于参数名称冲突,嵌套相同的标签名称将不起作用.此外,这个界面不能很好的工作(或者根本就不用VB).但是,对于其他现代.NET API,即使是来自Microsoft的PLINQ接口也是如此.

另一种我以前想过的方法实际上是试图效仿马卡比,就像sambo的代码一样.主要区别在于我使用块而不是foreach,因此使用RAII:

using (var body = writer.body("xml:lang","en")) {
    using (var h1 = body.h1())
        h1.AddText("Hello,World!");
    using (var p = body.p("style","color: red"))
        p.AddText("Indeed. What a lovely day.");
}

代码没有其他方法的问题.另一方面,它为属性提供了更少的类型安全性和较不优雅的界面(对于“优雅”的给定定义).

我得到两个代码来编译,甚至产生一些或多或少有意义的输出(即:HTML!).

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Mip是什么意思以及作用有哪些
怎么测试Mip页面运行情况
MIP安装的具体步骤有哪些
HTML添加超链接、锚点的方法及作用详解(附视频)
MIP的规则有哪些
Mip轮播图组件中的重要属性讲解
Mip的内联框架组件是什么
怎么创建初始的MIP配置及模板文件
HTML实现多选框及无法提交多数据的原因分析(附视频)
HTML如何设置复选框、单选框以及默认选项?(图文+视频)