2011-02-10 18 views
23

TagBuilder是構建HTML元素的不錯實現。但是 - 有些HTML元素可以有另一個元素(我稱之爲孩子)。我無法從Mvc課程中找到任何課程。嵌套TagBuilder -as TagBuilderTree-

問題;我應該實現幾個支持嵌套標籤的類(TagBuilderTree和TagBuilderNode)嗎?或者我錯過了什麼?

回答

39

您可以在獨立的TagBuilders中構建子元素,並將其生成的HTML放在父TagBuilder中。

這裏有一個例子:一個<select>一些<option> S(例如脫脂的簡潔)

TagBuilder select = new TagBuilder("select"); 

foreach (var language in languages) // never ye mind about languages 
{ 
    TagBuilder option = new TagBuilder("option"); 
    option.MergeAttribute("value", language.ID.ToString()); 

    if (language.IsCurrent) 
    { 
     option.MergeAttribute("selected", "selected"); 
    } 

    option.InnerHtml = language.Description; 
    // And now, the money-code: 
    select.InnerHtml += option.ToString(); 
} 
+0

我更喜歡實現TagBuilderTree和TagBuilderNode它會封裝我們項目的嵌套標籤,但我試圖找到答案爲什麼Razor不提供服務?因爲它對所有剃刀用戶來說都是必需的 – 2011-02-10 15:28:36

+0

您的意思是WebPages,而不是Razor。這對所有的開發者都是不必要的。你可以使用靜態助手來代替。 – SLaks 2011-02-10 15:29:27

+0

你是對的,我談論System.Web.Mvc.TagBuilder類。它沒有與剃刀引擎直接相關。所有引擎都可以使用它..我想知道爲什麼我們沒有TagBuilder作爲樹,並且我應該使用TagBuilder嵌套html標籤。或者我應該實現自己的TagBuilderTree和TagBuilderNode類? – 2011-02-10 19:18:49

2

OK,我決定在我自己的代碼庫做一個小測試。

我比較了這兩種方法來創建完全相同的最終HTML:

  1. 手動生成使用StringBuilder的
  2. 使用多個TagBuilders和嵌套內容

的HTML手動生成HTML使用一個StringBuilder:

 

    var sb = new StringBuilder(); 
    sb.AppendLine("<div class='control-group'>"); 
    sb.AppendFormat(" <label class='control-label' for='{0}_{1}'>{2}</label>", propObj.ModelType, propObj.ModelProperty, propObj.LabelCaption); 
    sb.AppendLine(" <div class='controls'>"); 
    sb.AppendFormat(" <input id='{0}_{1}' name='{0}[{1}]' value='{2}' />", propObj.ModelType, propObj.ModelProperty, propObj.PropertyValue); 
    sb.AppendLine(" </div>"); 
    sb.AppendLine("</div>"); 

    return new HtmlString(sb.ToString()); 
 

ù唱多TagBuilders和合並內容:


    TagBuilder controlGroup = new TagBuilder("div"); 
    controlGroup.AddCssClass("control-group"); 

    TagBuilder label = new TagBuilder("label"); 
    label.AddCssClass("control-label"); 
    label.InnerHtml = propObj.LabelCaption; 

    TagBuilder controls = new TagBuilder("div"); 

    TagBuilder input = new TagBuilder("input"); 
    input.Attributes["id"] = propObj.ModelType + "_" + propObj.ModelProperty; 
    input.Attributes["name"] = propObj.ModelType + "[" + propObj.ModelProperty + "]"; 
    input.Attributes["value"] = propObj.PropertyValue; 

    controls.InnerHtml += input; 

    controlGroup.InnerHtml += label; 
    controlGroup.InnerHtml += controls; 

    return new HtmlString(controlGroup.ToString()); 

對我來說,#1更容易閱讀和簡潔得多,但我的欣賞的#2還結構。

-2

我用TagBuilder創建標籤的問題是它看起來很不可維護。另一方面,StringBuilder的AppendFormat不僅使代碼可維護,而且運行效率很高。

我對MattSlay的#1方法做了一些改進。我只使用了一次對StringBuilder的AppendFormat方法的調用,並使用C#字符串文字來定義格式。結果格式最終看起來與期望的結果完全一樣,並且效率很高。

var sb = new StringBuilder(); 
    sb.AppendFormat(
    @"<div class='control-group'> 
      <label class='control-label' for='{0}_{1}'>{2}</label> 
      <div class='controls'> 
      <input id='{0}_{1}' name='{0}[{1}]' value='{3}' /> 
      </div> 
     </div>", 
     propObj.ModelType, 
     propObj.ModelProperty, 
     propObj.LabelCaption, 
     propObj.PropertyValue); 

    return new HtmlString(sb.ToString()); 

希望這會有所幫助!