2011-02-10 13 views
23

TagBuilderは、HTML要素を構築するための優れた実装です。しかし、いくつかのHTML要素は別の要素を持つことができます(私は子供のように呼びます)。私はMvcクラスからクラスを見つけることができませんでした。ネストされたTagBuilder -as TagBuilderTree-

質問;私はネストされたタグをサポートするいくつかのクラス(TagBuilderTreeとTagBuilderNode)を実装する必要がありますか?

答えて

39

別個のTagBuilderで子要素を構築し、生成したHTMLを親TagBuilderに入れることができます。

は、ここに例を示しますいくつかの<option> sの<select>(たとえば、簡潔さのために脱脂)

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がそれらのタグを提供しないのか答えを見つけようとしますか?すべてのRazorユーザーにとって必要なように見えるので、 –

+0

RazorではなくWebPagesを意味します。すべての開発者にとって必要というわけではありません。代わりに静的ヘルパーを使用することができます。 – SLaks

+0

あなたが正しいです、私はSystem.Web.Mvc.TagBuilderクラスについて話します。 Razorエンジンとは直接関係していません。すべてのエンジンがそれを使用できます。私はなぜTagBuilderをツリーとして持っていないのだろうかと疑問に思っています。また、TagBuilderを入れ子にしたhtmlタグに使うべきですか?あるいは私自身のTagBuilderTreeクラスとTagBuilderNodeクラスを実装する必要がありますか? –

2

OK、私は自分のコードベースで少しテストを行うことを決めました。

私はまったく同じ最終的なHTMLを作成するために、これらの2つの方法を比較した:

  1. 手動手動でHTMLを生成コンテンツ

を複数TagBuildersを使用し、ネストのStringBuilder

  • を使用して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()); 
     
    

    U複数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の構造をappreciatすることができます。

  • +0

    あなたが丁寧に注意を払わない場合は#1もスクリプト注入の可能な道です。私はちょうど追加したいと思います。 – Bon

    +2

    私は#1は、正しく閉じるタグ、一重引用符二重引用符などの正しい配置でHTMLをタイプすることに依存するので、#1はより多くのエラーを起こしやすいと思います。さらにTagBuilderにはよりインテリセンスがあります。たとえば、CSSクラスを追加する場合、stringbuilderはクラスを追加するためのインテリセンスを提供しませんが、TagBulderはIntelliSenseを持つAddCSSClassメソッドを持ちます。また、#2ははるかに読みやすくなっています。メソッド#1のすべてのプレースホルダは、物事をあまり明確にしません。 –

    -2

    TagBuilderでタグを作成する際に問題となるのは、非常に保守不能に見えるということです。一方、StringBuilderのAppendFormatは、コードを保守可能にするだけでなく、効率的に実行します。

    私はMattSlayの#1方法に少し改良を加えました。私はStringBuilderのAppendFormatメソッドへの呼び出しを1回しか使用せず、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()); 
    

    +0

    古い質問でした。あなたの提案は何ですか?クラスを「コントロールラベル」に変更します。すべてがハードasp.net(asp.netではなく)ページとしてハードコードされています。私はいつもメインテナンスはコードよりも重要だと思っています。 –

    +0

    入力の値がラベルのキャプションに設定されるため、これはうまくいくようには見えません。 MattSlayのバージョンでは、2つの異なるパラメータリストが使用されています。 ModelTypeとModelPropertyのコピーを取り除いてPropertyValueにアクセスできます。{3} – Robert

    +0

    @Robert複数呼び出しの代わりにAppendFormatを1回呼び出すだけで、TagBuilderとコードの保守性を得ることができることを実証しようとしましたMattSlayのようなAppendFormatへ。 AppendFormatへの一回の呼び出しに加えて、C#のStringリテラルが、読みやすいようにスペースでフォーマットされた文字列を定義する方法に注目してください。繰り返しますが、私はMattSlayのメソッドを改善しようとしていました:) –

    関連する問題