ASP.Net MVC3 - Пропускает разметку бритвы как параметр
У меня есть помощник по имени EditableArea
который предоставляет пользователю div
файл, редактируемый во время выполнения (через JS). Помощник EditableArea проверяет, существует ли в БД редактируемая область (не связанная с Area
MVC) с указанным идентификатором, если это так, то она отображает область HTML, в противном случае она отображает разметку по умолчанию, указанную в качестве параметра помощника:
@Html.EditableArea(someId, "<p>Click to edit contents</p>")
Все работает нормально, но я хотел бы изменить это так, чтобы разметка по умолчанию была указана не как строка, а как синтаксис бритвы, что-то вроде:
@using (Html.EditableArea(someId))
{
<p>Click to edit contents</p>
}
Или что - то подобное, как путь @section
работы в MVC3.
Как я могу этого достичь?
Я могу сделать IDisposable
который в своем Dispose
закрывает TagBuilder и т.д., Но при таком подходе разметка будет по-прежнему отображаться (я могу очистить визуализированное содержимое в Dispose()
но блок кода все равно будет запускаться без необходимости, что я ' хотел бы избежать).
И если я не использую using
есть ли какой-то другой способ передать блок бритвы помощнику, который может быть на самом деле или не может быть визуализирован?
Ответы
Ответ 1
Вот пример, который я использую для рендеринга jQuery Template, передавая в шаблоне Id и синтаксис стиля бритва для самого шаблона:
public static MvcHtmlString jQueryTmpl(this HtmlHelper htmlHelper,
string templateId, Func<object, HelperResult> template)
{
return MvcHtmlString.Create("<script id=\"" + templateId +
"\" type=\"x-jquery-tmpl\">" + template.Invoke(null) + "</script>");
}
и это будет вызвано с помощью
@Html.jQueryTmpl("templateId", @<text>any type of valid razor syntax here</text>)
В основном используйте Func<object, HelperResult>
как свой параметр и template.Invoke(null)
(с аргументами, если необходимо) для его рендеринга. Очевидно, вы можете пропустить вызов .Invoke()
, чтобы избежать рендеринга разметки по умолчанию.
Ответ 2
Просто, чтобы расширить принятый ответ, так как потребовалось некоторое время для решения подобной проблемы, и это вопрос, который возник. Я действительно нуждался в @helper
, который принимал бы текст бритвы, поскольку шаблон должен содержать довольно некоторый код. Я долго играл, пытаясь использовать несколько версий типа @helper item(Func<object, HelperResult> input)
, которые я нашел в Интернете, без успеха. Поэтому я пошел на такой подход, как:
namespace project.MvcHtmlHelpers
{
public static class HelperExtensions
{
public static MvcHtmlString RazorToMvcString(this HtmlHelper htmlHelper, Func<object, HelperResult> template)
{
return MvcHtmlString.Create(template.Invoke(null).ToString());
}
}
}
и
@project.MvcHtmlHelpers
@helper item(other input, MvcHtmlString content)
{
<div class="item">
...other stuff...
<div class="content">
@content
</div>
</div>
}
и используйте это через
@item(other input, @Html.RazorToMvcString(@<text>this is a test</text>))
Теперь я могу использовать вспомогательный шаблон для входа Razor, но я также могу отказаться от частичных представлений, что удобно в некоторых случаях. Поскольку я не эксперт, могут быть лучшие варианты, но это похоже на гибкий подход ко мне.
Ответ 3
Кроме того, можно передать разметку непосредственно помощнику без использования метода расширения.
@helper HelperWithChild(Func<object, HelperResult> renderChild)
{
<div class="wrapper">
@renderChild(this)
</div>
}
@HelperWithChild(@<h1>Hello</h1>)
Для многострочной разметки также требуется <text>
:
@HelperWithChild(@<text>
@AnotherHelper()
<h1>
With more markup
</h1>
</text>)
@helper AnotherHelper()
{
<p>
Another helper
</p>
}
Хотя я не уверен, как this
отразится на Model
- мои помощники используют только их параметры.