包括页面底部的 JavaScript,来自部分视图
Posted
技术标签:
【中文标题】包括页面底部的 JavaScript,来自部分视图【英文标题】:Including JavaScript at bottom of page, from Partial Views 【发布时间】:2011-12-31 17:05:35 【问题描述】:假设我有一个局部视图中的 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>
但是呃哦!我现在该怎么办,因为我的幻灯片脚本最终在我的 jQuery 包含之上?!如果我希望在每一页上都显示幻灯片,这没什么大不了的,但我只希望在某个页面上呈现幻灯片的部分视图,并且....我希望我的脚本在底部!怎么办?
【问题讨论】:
如果您不需要在每个页面上都使用该脚本,为什么要将其包含在 _Layout 中? 我想要每个页面上的 jQuery 库,因此在 _Layout.cshtml 中。我不想在每一页上都放映幻灯片……我关心的是 HTML 是如何呈现的。我希望能够在(渲染的)页面底部显示幻灯片脚本 【参考方案1】:您可以在布局页面中为这样的脚本定义一个部分:
<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>
然后,当页面呈现时,它将获取您部分中的所有内容并将其添加到布局页面上应该去的位置(在这种情况下,在底部)。
【讨论】:
太棒了,正是我想要的! 注意:这在局部视图中添加“部分”不起作用(因为只是平坦不起作用!)相反,我必须将“部分”添加到视图本身,但效果一样好! @ErOx 您是说该解决方案不适用于部分页面吗? @AaronLS 你是对的,它不适用于部分页面。您不能在局部视图中使用部分,您需要在包含局部视图的视图中添加部分。 在 .Net Core 2.1 中运行良好 :)【参考方案2】:注意:接受的解决方案将不起作用 对于部分视图,正如问题所要求的那样。
问题
在正常流程中,您可以使用 @section <i>SectionName</i>
声明从 ActionResult 的父视图内部定义特定部分的内容。当该视图最终插入其 LayoutPage 时,它可以调用 RenderSection
将这些内容放置在页面中的任何位置,允许您定义一些内联 JavaScript,这些 JavaScript 可以在任何核心库之后在页面底部呈现和解析它取决于这样:
当您希望能够在部分视图中重用完整页面视图时,就会出现问题。也许您还想将视图重新用作另一个页面内部的小部件或对话框。在这种情况下,无论您在父视图中对@Html.EditorFor
或@Html.Partial
进行调用,都会完整呈现完整的部分视图,如下所示:
根据MSDN Docs on Layouts with Razor Syntax:
视图中定义的部分仅在其直接布局页面中可用。 不能从局部视图、视图组件或视图系统的其他部分引用部分。 内容页面中的正文和所有部分都必须由布局页面呈现
在这种情况下,将定义到页面底部的部分视图中的脚本变得很棘手。根据文档,您只能从布局视图中调用 RenderSection
,并且不能从局部视图内部定义 @section
内容,因此所有内容都集中在同一区域中,您的脚本将被渲染、解析和运行从 HTML 页面的中间开始,而不是在底部,在它可能依赖的任何库之后。
解决方案
要全面讨论将部分视图中的部分注入页面的多种方法,我将从 *** 上的以下两个问题开始:
Injecting content into specific sections from a partial view with Razor View Engine Using sections in Editor/Display templates其中的不同解决方案在对嵌套、排序、多脚本支持、不同内容类型、调用语法和可重用性的支持上有所不同。但是,无论您如何切分它,几乎任何解决方案都必须完成两个基本任务:
-
从任何页面、部分视图或模板中逐步将脚本对象构建到您的请求中,可能会利用某种 HtmlHelper 扩展来实现可重用性。
将该脚本对象渲染到您的布局页面上。由于布局页面实际上是最后呈现的,因此这只是将我们一直在构建的对象发射到母版页上。
这是a simple implementationDarin 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()
【讨论】:
效果很好,即使是部分视图!以上是关于包括页面底部的 JavaScript,来自部分视图的主要内容,如果未能解决你的问题,请参考以下文章