问题
Given MVC3 and Razor engine, I got
_MasterLayout.cshtml
@RenderSection("JavaScript", required: false)
..
..
@RenderBody()
..
View.cshtml with _MasterLayout.cshtml defined in _ViewStart.cshtml
..
@Html.RenderAction("PartialView", "PartialController")
..
PartialView.cshtml
..
@section JavaScript
{
........
}
..
How can I make sure that JavaScript from Partial View ends up in the Master Layout section?
Edit
The above scenario doesn't work because the partial view doesn't have a master layout defined. View, on the other hand, does have Layout with RenderSection defined. If I move section JavaScript from Partial View to View, Razor knows where to render it to. But, since partial view doesn't have a layout, it doesn't know what to do with section JavaScript and thus doesn't render it anywhere.
回答1:
I don't believe a Partial View can set sections to be used in the layout page :(
It looks like there are no nice solutions to this - you could include two partials (one for script, one for content):
<script stuff>
@Html.RenderAction("PartialViewScripts", "PartialController")
</script stuff>
<body stuff>
@Html.RenderAction("PartialView", "PartialController")
</body stuff>
回答2:
I created a set of extension methods to render scripts blocks (or anything) from a partial, into the main layout.
public static class ViewPageExtensions
{
private const string SCRIPTBLOCK_BUILDER = "ScriptBlockBuilder";
public static MvcHtmlString ScriptBlock(
this WebViewPage webPage,
Func<dynamic, HelperResult> template)
{
if (!webPage.IsAjax)
{
var scriptBuilder = webPage.Context.Items[SCRIPTBLOCK_BUILDER]
as StringBuilder ?? new StringBuilder();
scriptBuilder.Append(template(null).ToHtmlString());
webPage.Context.Items[SCRIPTBLOCK_BUILDER] = scriptBuilder;
return new MvcHtmlString(string.Empty);
}
return new MvcHtmlString(template(null).ToHtmlString());
}
public static MvcHtmlString WriteScriptBlocks(this WebViewPage webPage)
{
var scriptBuilder = webPage.Context.Items[SCRIPTBLOCK_BUILDER]
as StringBuilder ?? new StringBuilder();
return new MvcHtmlString(scriptBuilder.ToString());
}
}
Then it can be used like so:
@this.ScriptBlock(
@<script type='text/javascript'>
$(document).ready(function () {
notify('@message', '@Model.Type.ToString()',
'@Model.Type.ToString().ToLower()');
});
</script>)
And then rendered in the main layout:
@this.WriteScriptBlocks()
Check out the full article here: A Script-Block Templated Delegate for Inline-Scripts in Razor Partials
回答3:
This worked for me allowing me to co-locate javascript and html for partial view in same file for ease of readability
In View which uses Partial View called "_MyPartialView.cshtml"
<div>
@Html.Partial("_MyPartialView",< model for partial view>,
new ViewDataDictionary { { "Region", "HTMLSection" } } })
</div>
@section scripts{
@Html.Partial("_MyPartialView",<model for partial view>,
new ViewDataDictionary { { "Region", "ScriptSection" } })
}
In Partial View file
@model SomeType
@{
var region = ViewData["Region"] as string;
}
@if (region == "HTMLSection")
{
}
@if (region == "ScriptSection")
{
<script type="text/javascript">
</script">
}
来源:https://stackoverflow.com/questions/5981490/how-to-render-javascript-into-masterlayout-section-from-partial-view