从局部视图
您可以使用HttpModule
来操作响应HTML并将任何CSS /脚本引用移动到适当的位置。这并不理想,我也不确定性能的影响,但它似乎是在没有(a)基于JavaScript的解决方案或(b)针对MVC原则的情况下解决问题的唯一方法。
您可以在JavaScript块中将部分视图加载到头部的样式中,但考虑到您可能希望头部的JavaScript块出于相同原因,这可能很愚蠢。
我最近发现了一些很酷的东西。您可以将部分视图序列化为一个字符串,并将其作为JSON对象的一部分发送回客户端。这使您可以传递其他参数以及视图。
Returning a view as part of a JSON object
你可以抓住用jQuery和Ajax JSON对象,并把它装载了局部视图,然后又是JSON财产可能是你的风格块。 JQuery可以检查你是否返回了一个样式块,如果是,则将其放入头部。
喜欢的东西:
$.ajax(
{
url: "your/action/method",
data: { some: data },
success: function(response)
{
$('#partialViewContainer).html(response.partialView);
if (response.styleBlock != null)
$('head').append(response.styleBlock);
}
});
良好的思维,这将工作,但它取决于用户启用了JavaScript(这是公平的,如果你正在加载脚本资源,但没有太多的CSS。) – kristian 2010-11-18 03:33:59
另一种方法,这违背了MVC的原则是使用视图模型,并到你的页面的Init事件来设置所需的CSS/JavaScript的(即myViewModel.Css回应。新增(“CSS”),并在你的脑袋上呈现您的视图模型的CSS-集合的内容。
要做到这一点,你创建你的所有车型,从继承的基础视图模型类,ALA
public class BaseViewModel
{
public string Css { get; set; }
}
在你的母版页设定要使用此视图模型
<%@ Master Language="C#" Inherits="System.Web.Mvc.ViewMasterPage<BaseViewModel>" %>
和你的头部分,你可以写出来的CSS属性的值现在
<head runat="server">
<title><asp:ContentPlaceHolder ID="TitleContent" runat="server" /></title>
<link href="../../Content/Site.css" rel="stylesheet" type="text/css" />
<%= Model.Css %>
</head>
,在您的局部视图你需要有这样的代码,这是MVC
<script runat="server">
protected override void OnInit(EventArgs e)
{
Model.Css = "hej";
base.OnInit(e);
}
</script>
即使OP没有提及ajax请求的部分,这当然会起作用,只是作为标准页面请求的一部分。我想挑战是让它适用于局部视图,无论是作为单个请求的一部分调用,还是作为ajax刷新(我不知道它是如何工作的,除非它通过javascript注入头部) – 2010-11-18 13:23:52
Yikes!我根本不喜欢这个。我宁愿违反保留头部部分样式的协议,也不愿意抛弃我的MVC应用程序中的问题。 – Chev 2010-11-18 21:16:27
您也可以使用Telerik的开源控件MVC和这样做有点难看:
<%= Html.Telerik().StyleSheetRegistrar()
.DefaultGroup(group => group
.Add("stylesheet.css"));
head部分
和
<%= Html.Telerik().ScriptRegistrar()
.DefaultGroup(group => group
.Add("script.js"));
在你的页面的botttom脚本部分
。
你可以在任何视图或局部视图上添加脚本,它们应该可以工作。
如果你不想使用该组件,你总是可以从那里激发你自己,做一些更自定义的事情。
哦,在Telerik中,您还可以选择合并和压缩脚本。
+1,我喜欢这个解决方案。虽然我很想知道Telerik如何做它的业务。我可能会去看看它。 – Chev 2010-11-18 21:18:20
只有启用了JavaScript,以下才有效。这是我使用完全相同的场景中的小帮手你提到:
// standard method - renders as defined in as(cp)x file
public static MvcHtmlString Css(this HtmlHelper html, string path)
{
return html.Css(path, false);
}
// override - to allow javascript to put css in head
public static MvcHtmlString Css(this HtmlHelper html,
string path,
bool renderAsAjax)
{
var filePath = VirtualPathUtility.ToAbsolute(path);
HttpContextBase context = html.ViewContext.HttpContext;
// don't add the file if it's already there
if (context.Items.Contains(filePath))
return null;
// otherwise, add it to the context and put on page
// this of course only works for items going in via the current
// request and by this method
context.Items.Add(filePath, filePath);
// js and css function strings
const string jsHead = "<script type='text/javascript'>";
const string jsFoot = "</script>";
const string jsFunctionStt = "$(function(){";
const string jsFunctionEnd = "});";
string linkText = string.Format("<link rel=\"stylesheet\" type=\"text/css\" href=\"{0}\"></link>", filePath);
string jsBody = string.Format("$('head').prepend('{0}');", linkText);
var sb = new StringBuilder();
if (renderAsAjax)
{
// join it all up now
sb.Append(jsHead);
sb.AppendFormat("\r\n\t");
sb.Append(jsFunctionStt);
sb.AppendFormat("\r\n\t\t");
sb.Append(jsBody);
sb.AppendFormat("\r\n\t");
sb.Append(jsFunctionEnd);
sb.AppendFormat("\r\n");
sb.Append(jsFoot);
}
else
{
sb.Append(linkText);
}
return MvcHtmlString.Create(sb.ToString());
}
用法:
<%=Html.Css("~/content/site.css", true) %>
作品对我来说,寿如上所述,只有当启用javascript,从而限制了其有效性一点。
如果您正在使用MVC3 &剃刀,给每个页面项目添加到您的部分最好的办法是: 1)从布局页 2)中调用RenderSection()声明你的孩子中的相应部分网页:
/Views/Shared/_Layout.cshtml:
<head>
<!-- ... Rest of your head section here ... ->
@RenderSection("HeadArea")
</head>
/Views/Entries/Index.cshtml:
@section HeadArea {
<link rel="Stylesheet" type="text/css" href="/Entries/Entries.css" />
}
得到的HTML页面,然后包括部分看起来像这样:
<head>
<!-- ... Rest of your head section here ... ->
<link rel="Stylesheet" type="text/css" href="/Entries/Entries.css" />
<head>
您的解决方案帮助了我。谢谢! – 2011-05-07 09:13:36
@Richard,你在这里描述的不是针对OP的问题,他是在谈论一个局部视图,而'_Layout.cshtml'是一个布局,而不是局部视图(包含在Index.cshtml中的实例',并且想要将脚本直接渲染到_layout.cshtml的'
'标签中。 – Shimmy 2012-11-13 06:55:31
您的问题已经回答了几次已经,http://*.com/questions/912755/include-javascript- file-in-partial-views&http://*.com/questions/885990/linking-javascript-libraries-in-user-controls。我们在这种情况下讨论css还是js并不重要。 – 2010-11-18 02:48:20
@BurningIce - 你说得对,资源的类型并不重要。您链接到的问题具有相同的接受答案,这对部分视图无效,因为他们无法使用asp:内容控件(解析器错误消息:内容控件必须是内容页面中的*控件或嵌套母版页引用母版页。)或者我错过了什么? – kristian 2010-11-18 03:24:34
嗯有趣的一点。我想唯一真正的方法是将你的脚本/ css分成他们自己的部分视图。然后渲染部分在头部分的asp:Content中。这是我所能想到的。 – Chev 2010-11-18 07:48:04