- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
在我看来,使用 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 和一个字符串值并返回实例所以可以链接调用。我在这个类上还有用于最常见属性的方法,例如“Name”、“Class”和“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 的接口(interface)膨胀甚至更多。
最佳答案
我看到两个问题:
Tag(Tagname, …)
。为什么不为每个标签名称提供扩展方法?诚然,这会使界面膨胀并且需要编写大量内容(=> 代码生成!)。这两个问题也许可以通过使用 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 肯定需要做更多的工作。特别是,由于参数名称冲突,嵌套相同的标记名称将不起作用。此外,此接口(interface)在 VB 中无法正常工作(或根本无法正常工作)。但是,不幸的是,对于其他现代 .NET API,甚至是 Microsoft 的 PLINQ 接口(interface)也是如此。
我前段时间想到的另一种方法实际上是在尝试模仿Markaby,就像sambo 的代码一样。主要区别是我使用 using
block 而不是 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.");
}
此代码没有其他方法的问题。另一方面,它为属性提供的类型安全性较低,接口(interface)也不太优雅(对于给定的“优雅”定义)。
我编译了这两个代码,甚至生成了一些或多或少有意义的输出(即:HTML!)。
关于.net - 用于呈现 HTML 的流畅界面,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/414605/
我想在单击按钮时进行移动:向左。这是针对移动运动的... 问题在于它的移动,但只有一次。我需要点击按钮发送垃圾邮件... 代码: 在创建中: this.buttonleft.inputEnabled
前言 今天大姚给大家分享一个.NET开源(MIT License)、免费、现代化、流畅、可测试、可移植的URL构建器和HTTP客户端库:Flurl。 项目介绍 Flurl是一个集现代性、流畅性、
我不确定其他与我的问题明显相似的问题是否归结为同一主题。 请考虑这段代码(为更清楚起见,为 head 部分提取了 CSS 代码): body { margin: 0;
我是一名学习 html/css 的学生,我在创建第一个网站时遇到了问题。我在配置页面时遇到了很多困难,因此它是流动的而不是固定的。我配置了一个框、图像和一些文本,因此它们在页面上是绝对的,但我无法使页
在我的游戏中,我已将角色设置为移动。它的设置方式是: if game_over_state == False: if event.type == pygame.KEYDOWN:
我一直在研究代码,但似乎无法让它工作。我用谷歌搜索,在这个网站上搜索了 13 页,但仍然找不到我要找的答案。 我希望视频以特定尺寸开始,然后随着我调整浏览器大小(从桌面到 iPad/iPhone)而缩
我已经从 sql server 2005 切换到 mysql,这并不是一个真正的问题。 我对 sql server 中存在的 (n)varchar 有一个小问题。通常我用过: mapping.Map(
我必须使用自定义 odbc 驱动程序。 我需要作为连接字符串传递的只是 DSN。 我如何使用(流畅)nhibernate 做到这一点? FluentNHibernate.Cfg.Db 仅提供带有 DS
我无法找到我们网站上动态显示的弹出窗口。最初该元素处于以下 html 状态: 使用jquery的show和hide,div显示5秒,稍后隐藏。 在我的 Selenium 脚本中,我尝试使用以下语句等
我有一个 two/three基于屏幕尺寸的列布局。 如果窗口大小大于 1000比我需要遵循 3 column其他布局我需要遵循 two column布局。 我是用JS实现的,但是代码很乱。现在我想用
我有一个 Flutter 应用程序,随着时间的推移和添加的功能越来越多,它变得越来越笨拙。因此,是否有一些实用程序可以使其像 60FPS 一样流畅? 我知道这里有一些官方指南:https://docs
我在如何实现 $(window).smartresize() 上纠结了几个小时使我的 div 流畅的功能。 我使用了这个 theme 中的 javascript但是当我尝试自己实现它时,我的 div
当我尝试通过 canvas.getContext('2d') 和 canvas.getContext('webgl') 将相同的 PNG 文件加载到 Canvas 中时,发现与canvas2d相比,w
我有一个所有实体的基类: public class BaseClass { public int SomeProperty {get; set;} } public class SomeEnt
我正在从事一个对时间相当敏感的元素。任务是制作一个微型网站,用户可以通过他们的智能手机访问该网站,在那里他们可以访问许多电影。他们会扫描二维码(我知道他们已经死了,我没有计划这次事件)。并登陆这个网站
我们正在使用Entity Framework 5.0。和数据库MySQL。当我们尝试迁移时间时出现异常。 could not be created because the principal key
快速问题:如何将传递给shiny.fluent::Text函数的文本设置为粗体?更广泛地说,如何将样式选项传递给此函数?。在函数的帮助页面中,它是这样写的。但我不明白如何使用这个变量参数。。我试着在不
我是一名优秀的程序员,十分优秀!