在使用Bootstrap编写用于ASP.NET MVC的Web应用程序的下一个过程中,我发现自己想必可以减去不可避免的HTML标签的创建。 这与扩展Html空间的用户控件无关,而是更远的地方。 急于求成,我建议您
在这里(GitHub)看看,其余的,欢迎关注。
挑战赛
有一个HTML标签,其中包含名称,类,样式,属性等。 在.NET中,为了“手动”创建这种外观,假定使用
TagBuilder类,并逐步用必要的元数据和公正数据填充它。
但是!
在我看来,经常使用该课程太沉闷了。 常量* .AddCssClass,* .Attributes.Add,* .MergeAttribute和* .ToString(TagRenderMode.SelfClosing)-在某些时候开始逐步惹恼他们。
这是一个标准按钮元素的示例:
<button type="button" class="btn btn-success">Success</button>
我们在此处添加的内容是,有时HTML标签需要嵌套,这意味着您需要一个或多个* .InnerHtml和一个参数,而每个参数又应以相同的方式创建-长步逐步-很明显,您需要一些东西一些不太常规的东西。
这就是
TagDecorator类的诞生方式。
我要解决的问题如下:-
简化HTML标签的创建,逐步进行并组织HTML层次结构的自然嵌套。解决方案
链接:
TagDecorator在初始阶段,解决方案由两类组成,但随后又添加了另一类:
TagDecorator是主要的工作类,负责将纯文本转换为表示标记的类(TagWrapper),可以在其上附加扩展名。 在现有示例中,既有通用函数AddAttribute,AddCss,又有私有函数AddType,AddName,AddId-创建特定的属性。
TagWrapper是表示标签的类。 它被创建为在可能的情况下完全脱离TagBuilder,并且IntelliSense中的新扩展名并未与TagBuilder类的属性混淆。
标签 -分隔开始/结束标签所需的类,以实现在RazorView中使用的框架HTML块
@using(Html.SuchExtension) {
例子
在指示的按钮示例中,使用TagDecorator的优势并不明显:
var htmlString = "button".ToTag() .AddType("button") .AddCss(new[] {"btn", "btn-success"}) .SetText("Success") .ToString();
但是现在以
Bootstrap卡为例-一切已经变得令人赏心悦目:
使用TagBuilder
var divMain = new TagBuilder("div"); divMain.AddCssClass("card"); divMain.Attributes.Add("style", "width: 18rem;"); var img = new TagBuilder("img"); img.AddCssClass("card-img-top"); img.Attributes.Add("src", "..."); img.Attributes.Add("alt", "Card image cap"); var divBody = new TagBuilder("div"); divBody.AddCssClass("card-body"); var h = new TagBuilder("h5"); h.AddCssClass("card-title"); h.SetInnerText("Card title"); var p = new TagBuilder("p"); p.AddCssClass("card-text"); p.SetInnerText("Some quick example text to build on the card title and make up the bulk of the card's content."); var a = new TagBuilder("a"); a.Attributes.Add("href", "#"); a.AddCssClass("btn"); a.AddCssClass("btn-primary"); a.SetInnerText("Go somewhere"); divBody.InnerHtml += h.ToString(TagRenderMode.Normal); divBody.InnerHtml += p.ToString(TagRenderMode.Normal); divBody.InnerHtml += a.ToString(TagRenderMode.Normal); divMain.InnerHtml += img.ToString(TagRenderMode.Normal); divMain.InnerHtml += divBody.ToString(TagRenderMode.Normal); return divMain.ToString(TagRenderMode.Normal);
带有TagDecorator的版本
var htmlString = "div".ToTag() .AddCss("card") .AddAttribute("style", "width: 18rem;") .InnerHtml(new [] { "img".ToTag() .AddCss("card-img-top") .AddAttributes(new[] {new[] {"src", "..."}, new[] {"alt", "Card image cap"}}), "div".ToTag() .AddCss("card-body") .InnerHtml(new [] { "h5".ToTag().AddCss("card-title").SetText("Card title"), "p".ToTag().AddCss("card-text").SetText("Some quick example text to build on the card title and make up the bulk of the card's content."), "a".ToTag().AddCss(new[] {"btn", "btn-primary"}).AddAttribute("href", "#").SetText("Go somewhere") }) }).ToString();
结果
缺点
我认为主要的观点是,级联实现有时会将代码向右移动,通常会超出开发人员的视野,并且层次结构越复杂,则代码越强大
优点
+代码行-减少。 在最简单的元素中,在复杂的HTML树中大约有1-2行的增益-如果使用TagBuilder,按类推,大约有1/3行。
+可见性-您可以清楚地看到嵌套的位置和种类。 一切都是层次直观的,易于理解。
+可扩展性-需要一些特定的情况/属性-只需添加扩展名即可。 需要条件检查-添加扩展。
可能的改进
最初,我考虑过基于这些类创建完全专用的标签,这些标签仅允许工具提示中的某些扩展-例如,删除button标签中的AddReference扩展工具提示,但随后为了通用起见放弃了这些计划。 但总的来说,这种解决方案现在对我的项目有很大帮助。
还应该创建一个NuGet程序包,但是由于时间不足-一切都被推迟了。