假设我在局部视图中有一个javascript幻灯片放映......
_Slideshow.cshtml:
@{
ViewBag.Title = "Slide Show";
}
<div id="slides">
</div>
<script src="js/slides.min.jquery.js"></script>
<script type="text/javascript">
$(function(){
$('#slides').slides({
// slide show configuration...
});
});
</script>
但我想成为一名优秀的小型Web开发人员,并确保我的所有脚本都位于页面底部。所以我会让我的* _Layout.cshtml *页面看起来像这样:
_Layout.cshtml:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>@ViewBag.Title</title>
<link href="@Url.Content("~/css/global.css")" rel="stylesheet" type="text/css" />
</head>
<body>
<div id="wrapper">
@RenderBody
</div>
<!-- Being a good little web developer, I include my scripts at the BOTTOM, yay!
-->
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js" type="text/javascript"></script>
</body>
</html>
但是UH OH!我现在该怎么做,因为我的幻灯片脚本最终超出了我的jQuery包含范围?!如果我想在每个页面上播放幻灯片,这不会是什么大不了的事,但我只希望幻灯片放映部分视图在某个页面上呈现,并且......我希望我的脚本在底部!怎么办?
答案 0 :(得分:9)
您可以在布局页面中为这样的脚本定义一个部分:
<body>
<div id="wrapper">
@RenderBody
</div>
<!-- Being a good little web developer, I include my scripts at the BOTTOM, yay!
-->
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js" type="text/javascript"></script>
@RenderSection("myScripts")
</body>
然后在您的页面上定义该部分的内容:
@{
ViewBag.Title = "Slide Show";
}
<div id="slides">
</div>
@section myScripts { //put your scripts here
<script src="js/slides.min.jquery.js"></script>
<script type="text/javascript">
$(function(){
$('#slides').slides({
// slide show configuration...
});
});
</script>
}
然后,当页面呈现时,它会将您的部分中的所有内容添加到应该放置在布局页面上的位置(在这种情况下,位于底部)。
答案 1 :(得分:3)
注意:已接受的解决方案无法正常工作 部分视图,如问题所示。
在正常流程中,您可以使用@section SectionName {}
声明从ActionResult上的父视图内部定义特定部分的内容。当该视图最终插入其LayoutPage时,它可以调用RenderSection
将这些内容放在页面内的任何位置,允许您定义一些内联JavaScript,可以在任何核心之后在页面底部呈现和解析像这样依赖的图书馆:
如果您希望能够在部分视图中重用整个页面视图,则会出现问题。也许您还想从另一个页面内部将视图重新用作窗口小部件或对话框。在这种情况下,只要您在父视图中将@Html.EditorFor
或@Html.Partial
的调用置于此处,就会完整呈现完整的部分视图:
根据MSDN Docs on Layouts with Razor Syntax:
- 视图中定义的部分仅在其直接布局页面中可用。
- 无法从视图系统的局部视图,视图组件或其他部分引用节。
- 内容页面中的正文和所有部分都必须由布局页面
呈现
在这种情况下,将定义到局部视图中的脚本放到页面底部变得很棘手。根据文档,您只能从布局视图中调用RenderSection
,并且无法从局部视图内部定义@section
内容,因此所有内容都会被集中到同一区域,您的脚本将被渲染,解析,并从HTML页面的中间运行,而不是在它可能依赖的任何库之后的底部。
有关将部分视图中的部分注入页面的多种方法的完整讨论,我将从StackOverflow上的以下两个问题开始:
其中不同的解决方案在支持嵌套,排序,多脚本支持,不同内容类型,调用语法和可重用性方面存在差异。但无论你如何分割它,几乎任何解决方案都必须完成两个基本任务:
此处a simple implementation Darin Dimitrov
添加帮助程序扩展方法,这些方法允许您将任意脚本对象构建到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;
}
}
然后你可以在你的应用程序中使用这样的
在部分视图中构建此类脚本对象,如下所示:
@Html.Script(
@<script>
$(function() {
$("#@Html.IdFor(model => model.FirstName)").change(function() {
alert("New value is '" + this.value + "'");
});
})
</script>
)
然后在 LayoutPage 中的任意位置渲染它们,如下所示:
@Scripts.Render("~/bundles/jquery")
@RenderSection("scripts", required: false)
@Html.RenderScripts()