4

古い MVC HTML ヘルパーでは、IDisposableコンテンツをラップするために使用できました。たとえば、ヘルパーは終了タグでBeginForm自動的にラップします。*stuff*form

<% using (Html.BeginForm()) {%>
   *stuff*
<% } %> 

このコンテンツのラッピングは MVC6 TagHelpers でサポートされていますか? たとえば、私はこれが欲しい

<widget-box title="My Title">Yay for content!</widget-box>

ラッピング div を使用してブートストラップ ウィジェット ボックスに展開します。

<div class="widget-box">
    <div class="widget-header">
        <h4 class="widget-title">My Title</h4>
    </div>
    <div class="widget-body">
        <div class="widget-main">
            Yay for content!
        </div>
    </div>
</div>

これは TagHelpers で可能ですか?

解決策: @DanielJG の回答を、WidgetBoxTagHelper.csを使用するgithubで動作するデモに焼き付けました(本番アプリで lib を使用しているため、Beta/RC/RTM で最新の状態を維持します)。

4

1 に答える 1

6

タグ ヘルパーはインターフェイスを実装する必要があり( @NTaylorMullenITagHelperで指摘されているように、クラスは実装時に使用できる便利なクラスにすぎません)、メソッドとを使用する必要があるため、メソッドにコンテンツを追加することに依存することはできません。TagHelperProcessProcessAsyncDispose

ただし、出力コンテンツを完全に制御できるため、必要に応じて置換/変更できます。たとえば、ウィジェット タグ ヘルパーの簡単な近似 (フレームワークの 1.0 バージョンを使用):

[HtmlTargetElement("widget-box")]
public class WidgetTagHelper : TagHelper
{
    public string Title { get; set; }

    public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
    {
        var outerTag = new TagBuilder("div");
        outerTag.Attributes.Add("class", output.TagName);
        output.MergeAttributes(outerTag);
        output.TagName = outerTag.TagName;

        //Create the header
        var header = new TagBuilder("div");
        header.Attributes.Add("class", "widget-header");
        header.InnerHtml.Append(this.Title);
        output.PreContent.SetHtmlContent(header);

        //Create the body and replace original tag helper content
        var body = new TagBuilder("div");
        body.Attributes.Add("class", "widget-body");
        var originalContents = await output.GetChildContentAsync();
        body.InnerHtml.Append(originalContents.GetContent());
        output.Content.SetHtmlContent(body);
    }
}

カミソリには次のものがあります。

<widget-box title="My Title">Yay for content!</widget-box>

次のようにレンダリングされます。

<div class="widget-box">
    <div class="widget-header">My Title</div>
    <div class="widget-body">Yay for content!</div>
</div>

_ViewImports.cshtmlファイル@addTagHelperにディレクティブを追加して、タグ ヘルパーをアセンブリに登録することを忘れないでください。たとえば、これは私のアプリケーションにすべてのヘルパーを登録します:

@addTagHelper *, WebApplication2

古い beta7 コード

  • beta7 では、[TargetElement]属性を使用する必要がありました。
  • TagBuilder クラスには、SetInnerTextそのコンテキストをテキストとして設定するために使用できるメソッドがありました。

コードは次のようになりました。

[TargetElement("widget-box")]
public class WidgetTagHelper : TagHelper
{
    private IHtmlEncoder encoder;
    public WidgetTagHelper(IHtmlEncoder encoder)
    {
        this.encoder = encoder;
    }

    public string Title { get; set; }

    public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
    {
        var outerTag = new TagBuilder("div");
        outerTag.Attributes.Add("class", output.TagName);
        output.MergeAttributes(outerTag);
        output.TagName = outerTag.TagName;

        //Create the header
        var header = new TagBuilder("div");
        header.Attributes.Add("class", "widget-header");
        header.SetInnerText(this.Title);
        output.PreContent.SetContent(header);

        //Create the body and replace original tag helper content
        var body = new TagBuilder("div");
        body.Attributes.Add("class", "widget-body");
        var originalContents = await context.GetChildContentAsync();           
        using (var writer = new StringWriter())
        {
            body.TagRenderMode = TagRenderMode.StartTag;
            body.WriteTo(writer, encoder);
            originalContents.WriteTo(writer, encoder);
            body.TagRenderMode = TagRenderMode.EndTag;
            body.WriteTo(writer, encoder);
            output.Content.SetContent(writer.ToString());
        }                            
    }
}

古い beta5 コード

  • InnerHtmlタグ ヘルパーにプロパティがありました。
  • ToHtmlStringそれらを html としてレンダリングするために使用されるタグ ヘルパーにメソッドがありました。

コードは次のようになりました。

[TargetElement("widget-box")]
public class WidgetTagHelper: TagHelper
{
    public string Title { get; set; }

    public override async Task ProcessAsync(TagHelperContext context, TagHelperOutput output)
    {
        var outerTag = new TagBuilder("div");
        outerTag.Attributes.Add("class", output.TagName);
        output.MergeAttributes(outerTag);
        output.TagName = outerTag.TagName;

        //Create the header
        var header = new TagBuilder("div");
        header.Attributes.Add("class", "widget-header");
        header.InnerHtml = this.Title;
        output.PreContent.SetContent(header.ToHtmlString(TagRenderMode.Normal).ToString());

        //Create the body and replace original tag helper content
        var body = new TagBuilder("div");
        body.Attributes.Add("class", "widget-body");
        var originalContents = await context.GetChildContentAsync();
        body.InnerHtml = originalContents.GetContent();
        output.Content.SetContent(body.ToHtmlString(TagRenderMode.Normal).ToString());
    }
}
于 2015-07-22T09:09:29.100 に答える