用我的意見來渲染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