Подтвердить что ты не робот

Синтаксис Razor - как условно обернуть некоторый внутренний HTML

В Razor существует любопытное правило только разрешать закрытый HTML в блоке if.

См:

Razor не понимает открытые html-теги

Но у меня есть ситуация, когда я хочу исключить некоторые внешние, обертывающие элементы при определенных условиях. Я не хочу повторять весь внутренний HTML, что является достаточным количеством HTML и логики.

Единственный путь вокруг проблемы - сделать еще одно частичное представление для внутреннего материала, чтобы он был DRY?

Без какого-либо другого повторного использования для этого нового частичного, он чувствует себя действительно неудобно, раздутый. Интересно, является ли правило ограничением Razor или просто функцией nannying (раздражает).

4b9b3361

Ответ 1

Вы можете использовать Html.Raw(mystring). В myString вы можете писать все, что хотите, например, открытие или закрытие тега, без каких-либо ошибок. То есть.

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

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

ПРИМЕЧАНИЕ. @Html.Raw("<div>") можно записать в более короткой альтернативной форме, например: @:<div>

Вы также можете создать свои собственные html-помощники для упрощения синтаксиса бритвы. Эти помощники могут получить параметр условия, чтобы вы могли сделать что-то вроде этого:

@Html.DivOpen(condition)

@Html.DivClose(condition)

или более сложные помощники, которые позволяют указывать атрибуты, имя тега и т.д.

И не Raw, ни html-помощники не будут найдены как "теги", поэтому вы можете свободно их использовать.

Лучший способ сделать это

Было бы гораздо безопаснее реализовать что-то вроде BeginForm html-помощника. Вы можете посмотреть исходный код. Его легко реализовать: вам просто нужно написать открывающий тег в конструкторе и закрывающий тег в методе 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()
  }

Какой класс использует класс:

  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));
       }
  }

Вы можете использовать это с тем же шаблоном, что и BeginForm. (Отказ от ответственности: этот код не полностью протестирован, но дает представление о том, как он работает. Вы можете принимать дополнительные параметры для атрибутов, имен тегов и т.д.).

Ответ 2

Объявите бритвенный помощник, используя @helper HeplerName(), вызовите @HeplerName() где угодно. И вы можете добавить параметры, если хотите.

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

@helper MyContent()
{
  <img src="/img1.jpg" />
}