Razor语法 - 如何有条件地包装一些内部HTML

Luk*_*ett 17 html asp.net-mvc razor

在Razor中,有一个奇怪的规则,即只允许在一个块内封闭 HTML if.

看到:

Razor不理解unclosed html标签

但我有一种情况,我想在某些条件下排除一些外部包裹元素.我不想重复所有内部HTML,这是相当数量的HTML和逻辑.

围绕这个问题的唯一方法是为内部的东西制作另一个部分视图以保持干燥吗?

没有任何其他重新使用这个新的部分,它感觉真的很尴尬,臃肿.我想知道这条规则是Razor的限制还是简单的纳米(烦人)功能.

Jot*_*aBe 31

你可以用Html.Raw(mystring).在myString你可以写任何你想要的东西,例如标签打开或关闭,而不会有任何错误.即

if (condition) {
  @Html.Raw("<div>")
}

if (condition) {
  @Html.Raw("</div>")
}
Run Code Online (Sandbox Code Playgroud)

注意:@Html.Raw("<div>")可以用更短的替代形式编写,如下所示:@:<div>

您还可以创建自己的html助手,以简化剃刀语法.这些助手可以接收条件参数,以便您可以执行以下操作:

@Html.DivOpen(condition)

@Html.DivClose(condition)
Run Code Online (Sandbox Code Playgroud)

或更复杂的帮助程序,允许指定属性,标记名称等.

也不是Raw,html帮助器都不会被检测为"标签",因此您可以自由使用它们.

最好的方法

实现类似BeginFormhtml帮助器的东西会更安全.您可以查看源代码.它易于实现:您只需在构造函数中编写开始标记,并在Dispose方法中编写结束标记.这种技术的优点是你不会忘记关闭有条件打开的标签.

您需要实现此html帮助程序(在静态类中声明的扩展方法):

  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()
  }
Run Code Online (Sandbox Code Playgroud)

哪个使用这样的类:

  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));
       }
  }
Run Code Online (Sandbox Code Playgroud)

您可以使用与此相同的模式BeginForm.(免责声明:此代码未经过全面测试,但可以了解其工作原理.您可以接受属性,标签名称等的额外参数).


Iva*_*lov 5

使用@helper HeplerName(),在@HeplerName()任何地方调用来声明剃刀助手。如果需要,您可以添加参数。

@if (condition)
{
  <div class="wrapper">
    @MyContent()
  </div>
}
else
{
  @MyContent()
}

@helper MyContent()
{
  <img src="/img1.jpg" />
}
Run Code Online (Sandbox Code Playgroud)

编辑(感谢@Kolazomai 在评论中提出这一点):

ASP.NET Core 3.0 不再支持@helper但支持方法主体中的 HTML 标记。新案例将如下所示:

@if (condition)
{
  <div class="wrapper">
    @{ MyContent(); }
  </div>
}
else
{
  @{ MyContent(); }
}

@{
  void MyContent()
  {
    <img src="/img1.jpg" />
  }
}
Run Code Online (Sandbox Code Playgroud)