2015-07-22 3 views
4

В старых MVC HTML Helpers, можно было бы использовать IDisposable завернуть контент - например, BeginForm помощник будет автоматически оберните *stuff* с закрытием form тегомMVC6 TagHelpers с одноразовыми

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

Это обертывание содержания поддерживается MVC6 TagHelpers? Например, я хотел бы это

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

быть расширен в загрузочном виджет коробки с обертыванием дивы:

<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 в в working demo on github потребляющий WidgetBoxTagHelper.cs (будет оставаться в курсе Beta/RC/RTM, как я использую Либерал в моей версии приложения)

ответ

6

Tag Помощники должны осуществлять интерфейс ITagHelper (как указано на @NTaylorMullen, то TagHelper класс просто класс удобства вы можете использовать при его реализации), который заставляет вас использовать методы Process и ProcessAsync, так что вы не можете полагаться на добавление содержимого в методе Dispose.

Однако у вас есть полный контроль над выходным контентом, чтобы вы могли его заменить или модифицировать по мере необходимости. Например, быстрое приближение к вашему помощнику тегов виджета (Используя версию инфраструктуры 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> 

Не забудьте зарегистрировать хелперов тегов в сборке, добавив @addTagHelper директиву _ViewImports.cshtml файл. Например, это будет регистрировать все хелперы в моем приложении:

@addTagHelper *, WebApplication2 

OLD код 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()); 
     }        
    } 
} 

OLD код beta5

  • Был InnerHtml свойство в теге хелперов.
  • В методах, используемых для рендеринга их в качестве html, использовался метод ToHtmlString.

код выглядел так:

[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()); 
    } 
} 
+0

сэр, +1 чувствует себя неадекватным. Спасибо. – fiat

+0

Добро пожаловать @fiat. Его интересно играть с asp .net 5 :). Кстати, я только что видел ваш репортаж github, хорошая идея! –

+2

Дополнительное примечание. Чтобы быть допустимым «TagHelper», вам просто нужно реализовать интерфейс «ITagHelper». Класс «TagHelper» - просто приятная базовая реализация :) –