有没有办法从局部视图添加CSS引用到页面, 并让它们在页面中呈现 <head>
(根据要求) HTML 4.01规范)?
有没有办法从局部视图添加CSS引用到页面, 并让它们在页面中呈现 <head>
(根据要求) HTML 4.01规范)?
如果您使用的是MVC3和Razor,那么将每页项目添加到您的部分的最佳方法是: 1)从布局页面中调用RenderSection() 2)在子页面中声明相应的部分:
/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>
您还可以使用Telerik的开源控件来执行MVC,并执行以下操作:
<%= Html.Telerik().StyleSheetRegistrar()
.DefaultGroup(group => group
.Add("stylesheet.css"));
在头部 和
<%= Html.Telerik().ScriptRegistrar()
.DefaultGroup(group => group
.Add("script.js"));
在页面底部的脚本部分。
您可以继续在任何视图或部分视图上添加脚本,它们应该可以工作。
如果您不想使用该组件,您可以随时从那里激发自己,并做一些更自定义的事情。
哦,对于Telerik,您还可以选择组合和压缩脚本。
你可以将一个javascript块中的部分视图加载到头部的样式中,但考虑到你可能想要头部中的javascript块出于同样的原因,这将是愚蠢的。
我最近发现了一些很酷的东西。您可以将部分视图序列化为字符串,并将其作为JSON对象的一部分发送回客户端。这使您可以传递其他参数以及视图。
您可以使用JQuery和ajax获取JSON对象,并使用部分视图加载它,然后另一个JSON属性可能是您的样式块。 JQuery可以检查你是否返回了样式块,如果是,则将其放入head部分。
就像是:
$.ajax(
{
url: "your/action/method",
data: { some: data },
success: function(response)
{
$('#partialViewContainer).html(response.partialView);
if (response.styleBlock != null)
$('head').append(response.styleBlock);
}
});
你可以用一个 HttpModule
操纵响应HTML并将任何CSS /脚本引用移动到适当的位置。这不是理想的,我不确定性能影响,但它似乎是解决问题的唯一方法,没有(a)基于javascript的解决方案,或(b)反对MVC原则。
另一种违背MVC原则的方法是使用ViewModel并响应页面的Init事件来设置所需的css / javascript(即myViewModel.Css.Add(“。css”)并在你的头部呈现viewmodel上的css-collection的内容。
为此,您需要创建一个基本的viewmodel类,其他所有模型都继承自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>
以下仅在启用了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的情况下才能为我工作,从而限制了它的实用性。