Примечание : принятое решение не будет работать для частичных представлений , когда задается вопрос.
Проблема
В обычном потоке вы можете определить содержимое для определенного раздела из родительского представления вашего ActionResult с помощью объявления @section <i>SectionName</i> {}
. И когда это представление, наконец, вставляется в его LayoutPage, оно может вызвать RenderSection
, чтобы поместить это содержимое в любое место на странице, позволяя вам определить некоторый встроенный JavaScript, который можно отобразить и проанализировать в нижней части страница после любых основных библиотек, от которых это зависит, вот так:
Full View">
Проблема возникает, когда вы хотите иметь возможность повторно использовать полный просмотр страницы внутри частичного просмотра. Возможно, вы хотели бы также повторно использовать вид в качестве виджета или диалога внутри другой страницы. В этом случае полное частичное представление отображается полностью, куда бы вы ни отправили вызов @Html.EditorFor
или @Html.Partial
внутри родительского представления следующим образом:
Parent View > Partial View">
В соответствии с документами MSDN для макетов с синтаксисом Razor :
- Разделы, определенные в представлении, доступны только на его непосредственной странице макета.
- На секции нельзя ссылаться из частичных элементов, компонентов представления или других частей системы представления.
- Тело и все разделы на странице содержимого должны отображаться на странице макета
В этом случае становится сложным получить сценарий, определенный в частичном представлении внизу страницы. Согласно документам, вы можете вызывать RenderSection
только из вида компоновки, и вы не можете определить содержимое @section
изнутри частичного представления, поэтому все будет сосредоточено в одной и той же области, и ваш скрипт будет обработан, проанализирован и запущен от середины вашей HTML-страницы, а не снизу, после любых библиотек, от которых она может зависеть.
Решение
Для полного обсуждения многих способов добавления разделов из частичных представлений на вашу страницу я бы начал со следующих двух вопросов о StackOverflow:
Различные решения в них отличаются друг от друга поддержкой вложенности, упорядочивания, поддержкой нескольких сценариев, различными типами содержимого, синтаксисом вызова и возможностью повторного использования. Но как бы вы ни разрезали его, практически любое решение должно будет решить две основные задачи:
- Постепенно создавайте объекты скрипта по вашему запросу из любой страницы, частичного представления или шаблона, возможно, используя какое-то расширение HtmlHelper для повторного использования.
- Визуализируйте этот объект сценария на странице макета. Поскольку страница макета фактически отображается последней, это просто излучение объекта, который мы создали, на главную страницу.
Вот простая реализация Дарин Димитров
Добавьте вспомогательные методы расширения, которые позволят вам создавать произвольные объекты сценариев в коллекции ViewContent.HttpContext.Items
, а затем извлекать и отображать их позже.
Utilities.cs
public static class HtmlExtensions
{
public static MvcHtmlString Script(this HtmlHelper htmlHelper, Func<object, HelperResult> template)
{
htmlHelper.ViewContext.HttpContext.Items["_script_" + Guid.NewGuid()] = template;
return MvcHtmlString.Empty;
}
public static IHtmlString RenderScripts(this HtmlHelper htmlHelper)
{
foreach (object key in htmlHelper.ViewContext.HttpContext.Items.Keys)
{
if (key.ToString().StartsWith("_script_"))
{
var template = htmlHelper.ViewContext.HttpContext.Items[key] as Func<object, HelperResult>;
if (template != null)
{
htmlHelper.ViewContext.Writer.Write(template(null));
}
}
}
return MvcHtmlString.Empty;
}
}
Тогда вы можете использовать это в своем приложении
Создайте объекты этого скрипта внутри своего Частичного представления , например:
<b>@Html.Script(</b>
<i>@<script>
$(function() {
$("#@Html.IdFor(model => model.FirstName)").change(function() {
alert("New value is '" + this.value + "'");
});
})
</script></i>
<b>)</b>
А затем визуализируйте их в любом месте в пределах вашей LayoutPage , например:
@Scripts.Render("~/bundles/jquery")
@RenderSection("scripts", required: false)
<b>@Html.RenderScripts()</b>