Как я могу создать повторно использовать пользовательские HTML-панели в ASP.NET в MVC?


Я пытаюсь создать многоразовый элемент пользовательского интерфейса в ASP.NET MVC, который оборачивается вокруг любого контента, который я решаю разместить в нем. Моей первой мыслью было создать частичное представление, но это, похоже, не помогает мне в том, что я пытаюсь сделать.

Шаблон

Например, я хотел бы создать некоторую многоразовую разметку, подобную этой (извините за псевдокод):

<div class="panel panel-default">
  <div class="panel-body">
    @RenderBody()
  </div>
</div>

Простой Пример

Тогда, по моему мнению, я хотел бы сделать что-то подобное это:

@Render.Partial("MyPanel")
{
    <img src="image.jpg" />
}

Предполагая, что код работает так, как ожидалось, он будет генерировать следующее:

<div class="panel panel-default">
  <div class="panel-body">
     <img src="image.jpg" />
  </div>
</div>

Другой пример, с более сложной разметкой

Теоретически я хотел бы иметь возможность поместить все, что я хотел бы, в одну из панелей. Так что даже более сложная разметка все равно будет казаться разборчивой.
@Render.Partial("MyPanel")
{
    <form>
      <div class="form-group">
        <label for="exampleInputEmail1">Email address</label>
        <input type="email" class="form-control" id="exampleInputEmail1" placeholder="Enter email">
      </div>
      <div class="form-group">
        <label for="exampleInputPassword1">Password</label>
        <input type="password" class="form-control" id="exampleInputPassword1" placeholder="Password">
      </div>
      <div class="form-group">
        <label for="exampleInputFile">File input</label>
        <input type="file" id="exampleInputFile">
        <p class="help-block">Example block-level help text here.</p>
      </div>
      <div class="checkbox">
        <label>
          <input type="checkbox"> Check me out
        </label>
      </div>
      <button type="submit" class="btn btn-default">Submit</button>
    </form>
}

Так же, как и в первом примере, он обернет все внутри верхнего и нижнего колонтитулов моего шаблона:

<div class="panel panel-default">
  <div class="panel-body">
    <form>
      <div class="form-group">
        <label for="exampleInputEmail1">Email address</label>
        <input type="email" class="form-control" id="exampleInputEmail1" placeholder="Enter email">
      </div>
      .. truncated ..
      <button type="submit" class="btn btn-default">Submit</button>
    </form>
  </div>
</div>

Известно Возможности

  • Частичный Вид.Частичное представление, по-видимому, имеет смысл, за исключением того, что я не смог найти способ создать частичное представление, обладающее гибкостью, выходящей за рамки модели, для которой оно было разработано. Я привел два примера, потому что содержимое моей панели может существенно отличаться каждый раз, когда я ее использую. Я хотел бы иметь возможность бросить что-нибудь в тело этого частичного представления; текст, разметку, больше кода бритвы и т. д.
  • HTML Helper. это прекрасно работает когда у меня есть определенные параметры, я буду передавать их. Я не считаю это практичным, когда нужно вводить большие объемы разметки, так как это будет трудно читать/поддерживать. Кроме того, поскольку html будет передаваться в виде строки, я не уверен, как это будет работать с тегами razor?
  • 2 Частичных Вида. используя один в качестве заголовка, а другой в качестве нижнего колонтитула. Это работает, но мне кажется, что это просто небрежно.

Я смог сделать это в ASP.NET веб-формы путем создания пользовательских контроль. Похоже, что это то, что должно быть прямо вперед в MVC тоже, но я просто еще не совсем смог найти хорошее решение.

2 2

2 ответа:

Вы можете использовать "DynamicInvoke" для создания HTML-помощников с динамической разметкой, таких как:

public static IHtmlString CustomPanel(this HtmlHelper htmlHelper, Func<object, object> panelMarkup = null)
{
    return CustomPanel(htmlHelper, (panelMarkup == null ? "" : panelMarkup.DynamicInvoke(htmlHelper.ViewContext).ToString()));
}

public static IHtmlString CustomPanel(this HtmlHelper htmlHelper, string content)
{
    TagBuilder div = new TagBuilder("div");
    div.AddCssClass("panel panel-default");

    TagBuilder innerDiv = new TagBuilder("div");
    innerDiv.AddCssClass("panel-body");

    innerDiv.InnerHtml = content;
    div.InnerHtml = innerDiv.ToString();

    return new HtmlString(div.ToString());
}

И тогда вы бы использовали его следующим образом:

@Html.CustomPanel(
    @<text>
        <div>My Custom Markup</div>
        <span>More Stuff</span>
    </text>
)

Ваш окончательный контент будет выглядеть следующим образом:

<div class="panel panel-default">
    <div class="panel-body">
        <div>My Custom Markup</div>
        <span>More Stuff</span>
    </div>
</div>

Вы видите, что это часто используется в некоторых сторонних библиотеках виджетов (kendo-ui является основным, о котором я знаю)

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

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

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

Http://weblogs.asp.net/scottgu/asp-net-mvc-3-and-the-helper-syntax-within-razor

Однако основная структура будет выглядеть следующим образом:

@helper MyHelper(string content)
{
     <div class="panel panel-default">
         <div class="panel-body">
             @Html.Raw(content)
         </div>
     </div>
}

Тогда вы используете его следующим образом:

@MyHelper("<img src="image.jpg" />")
Вам не нужно использовать строки, вы можете использовать структурированный контент, модели и т. д.. вы можете использовать других помощников внутри. Вы можете повторно использовать их, как описано далее в статье.

Возможно, вы захотите начать думать о своих страницах как о более ориентированных на данные, однако. Если вы используете EditorTemplates для отображения ваших данных, то вы будете отображать элементы управления на основе типа ваших данных, а не отрисовывать страницы и пытаться адаптировать страницы для хранения ваших данных.