Razor syntax - how to conditionally wrap some inner HTML

前端 未结 4 1897
滥情空心
滥情空心 2021-02-02 12:42

In Razor, there\'s a curious rule about only allowing closed HTML within an if block.

See:

Razor doesn't understand unclosed ht

4条回答
  •  清酒与你
    2021-02-02 12:47

    You can use Html.Raw(mystring). In myString you can write whatever you want, for example a tag opening or closing, without getting any errors at all. I.e.

    if (condition) {
      @Html.Raw("
    ") } if (condition) { @Html.Raw("
    ") }

    NOTE: the @Html.Raw("

    ") can be written in a shorter, alternative form, like this: @:

    You can also create your own html helpers for simplifying the razor syntax. These helpers could receive the condition parameter, so that you can do something like this:

    @Html.DivOpen(condition)
    
    @Html.DivClose(condition)
    

    or more complicated helpers that allow to specify attributes, tag name, and so on.

    Nor the Raw, neither the html helpers will be detected as "tags" so you can use them freely.

    The Best Way to do it

    It would be much safer to implement something like the BeginForm html helper. You can look at the source code. It's easy to implement: you simply have to write the opening tag in the constructor, and the closing tag in the Dispose method. The adavantage of this technique is that you will not forget to close a conditionally opened tag.

    You need to implement this html helper (an extension method declared in a static class):

      public static ConditionalDiv BeginConditionalDiv(this HtmlHelper html, 
        bool condition)
      {
          ConditionalDiv cd = new ConditionalDiv(html, condition);
          if (condition) { cd.WriteStart(); }
          return cd; // The disposing will conditionally call the WriteEnd()
      }
    

    Which uses a class like this:

      public class ConditionalDiv : IDisposable
      {
          private HtmlHelper Html;
          private bool _disposed;
          private TagBuilder Div;
          private bool Condition;
    
          public ConditionalDiv(HtmlHelper html, bool condition)
          {
              Html = html;
              Condition = condition;
              Div = new TagBuilder("div");
          }
    
          public void Dispose()
          {
              Dispose(true /* disposing */);
              GC.SuppressFinalize(this);
          }
    
          protected virtual void Dispose(bool disposing)
          {
            if (!_disposed)
            {
                _disposed = true;
                if (Condition) { WriteEnd(); }
            }
          }
    
           public void WriteStart()
           {
               Html.ViewContext.Writer.Write(Div.ToString(TagRenderMode.StartTag));
           }
    
           private void WriteEnd()
           {
               Html.ViewContext.Writer.Write(Div.ToString(TagRenderMode.EndTag));
           }
      }
    

    You can use this with the same pattern as BeginForm. (Disclaimer: this code is not fully tested, but gives an idea of how it works. You can accept extra parameters for attributes, tag names and so on).

提交回复
热议问题