在我的MVC 2网站中,我有一个html帮助器,我用它为我的页面添加javascripts。在我的母版页中,我有我想要包含的主要javascripts,然后在aspx页面中,我包含页面特定的javascripts。
例如,我的Site.Master有这样的东西:
....
<head>
<%=html.renderScripts() %>
</head>
...
//core scripts for main page
<%html.AddScript("/scripts/jquery.js") %>
<%html.AddScript("/scripts/myLib.js") %>
....
然后在子aspx页面中,我可能还想包含其他脚本。
...
//the page specific script I want to use
<% html.AddScript("/scripts/register.aspx.js") %>
...
因此,当整页被渲染时,javascript文件全部被网站管理员占位符函数RenderScripts收集并呈现在头部。这很好。
现在使用MVC 3和razor视图引擎,它们的布局页面表现不同,因为现在我的页面级别javascripts不会被渲染/包含。现在我只看到了LayoutMaster的内容。
如何使用MVC 3和剃刀视图引擎获得解决方案。 (已经重写了帮助程序以返回HTMLString ;-))
供参考:我的MasterLayout看起来像这样:
...
...
<head>
@{
Html.AddJavaScript("/Scripts/jQuery.js");
Html.AddJavaScript("/Scripts/myLib.js");
}
//Render scripts
@html.RenderScripts()
</head>
....
,子页面如下所示:
@{
Layout = "~/Views/Shared/MasterLayout.cshtml";
ViewBag.Title = "Child Page";
Html.AddJavaScript("/Scripts/register.aspx.js");
}
....
<div>some html </div>
感谢您的帮助。
编辑=只是解释,如果这个问题不够清楚。
在制作“页面”时,我会收集设计师想要使用的所有javascript文件,使用html.addJavascript(“filename.js”)并将它们存储在字典中 - (1)阻止人们添加重复的js文件 - 最后当页面准备渲染时,我会在标题中整齐地写出所有的javascript文件。 (2) - 这个帮助器有助于将JS保存在一个地方,并阻止设计人员在整个地方添加javascript文件。这曾经在mvc 2中使用Master / SiteMaster页面正常工作。但是如何用剃刀实现这一目标?
编辑:html助手代码:
....
private const string SCRIPTLINK =
"<script src=\"{0}\" type=\"text/javascript\"></script>";
public static HtmlString RenderScripts(this HtmlHelper helper) {
OrderedDictionary scripts =
helper.ViewContext.HttpContext.Items["JavaScripts"] as OrderedDictionary;
StringBuilder sb = new StringBuilder(500);
foreach (DictionaryEntry script in scripts) {
sb.AppendFormat(SCRIPTLINK, script.Key);
}
return new HtmlString(sb.ToString());
}
....
答案 0 :(得分:3)
如果没有看到HtmlHelpers的代码,很难帮助您使用当前的解决方案。然而,替代(并且相当普遍)的方法是使用Razor部分。
在您的布局页面中使用@RenderSection()
<head>
<title>Page Title</title>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js" type="text/javascript"></script>
@RenderSection("Scripts", required: false)
</head>
然后在您的视图中定义您的部分内容
@section Scripts {
<script src="myscript.js" type="text/javascript"></script>
}
如果你想节省一些打字并使它更干净,你可以创建一个HtmlHelper来输出你的脚本标签
public static MVcHtmlString AddScript(this HtmlHelper helper, string path) {
//create script element html here
}
然后你可以使用与你的例子类似的语法风格
@section Scripts {
@Html.AddScript("myscript.js")
}
答案 1 :(得分:2)
您的代码可能正在为布局页面和视图使用单独的词典。
尝试将字典存储在ViewBag
或HttpContext.Items
。
答案 2 :(得分:1)
感谢Slaks和David的帮助和提示。我终于得到了一个似乎有效的解决方案,但有一些我不喜欢的东西。如果有更好的方法,请随时指出。
这是我的孩子页面:
@{
ViewBag.Title = "Child Page";
}
@section Scripts {
@{Html.AddJavaScript("/Scripts/register.aspx.js");}
}
<div>some html </div>
然后我有一个_ViewStart.cshtml:
@{
this.Context.Items.Add("JavaScripts",
new System.Collections.Specialized.OrderedDictionary());
Layout = "~/Views/Shared/MasterLayout.cshtml";
}
我的MasterLayout看起来像这样:
<html>
....
<title>@ViewBag.Title</title>
<head>
@{
//core scripts
html.AddScript("/scripts/jquery.js");
html.AddScript("/scripts/myLib.js");
....
}
@RenderSection("Scripts", required:true)
//Have to call render scripts here, but not sure about this?
@Html.RenderScripts()
</head>
....
</html>
这会以正确的顺序和位置呈现我的脚本标记,但是需要客户端在子页面中调用html帮助器renderScripts。这没关系,因为我们可以创建模板来帮助解决这个问题。有更好的想法吗?