12

有没有办法从局部视图中添加对页面的 CSS 引用,并让它们在页面中呈现<head>(根据HTML 4.01 规范的要求)?

4

6 回答 6

6

如果您使用的是 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>
于 2011-02-13T22:21:03.183 回答
3

您还可以使用 Telerik 的 MVC 开源控件并执行以下操作:

<%= Html.Telerik().StyleSheetRegistrar()
                  .DefaultGroup(group => group
                     .Add("stylesheet.css"));

在头部和

<%= Html.Telerik().ScriptRegistrar()
                  .DefaultGroup(group => group
                     .Add("script.js"));

在页面底部的脚本部分。

您可以继续在任何视图或部分视图上添加脚本,它们应该可以工作。

如果您不想使用该组件,您总是可以从那里激发自己并做一些更自定义的事情。

哦,使用 Telerik,您还可以选择组合和压缩脚本。

于 2010-11-18T13:11:42.713 回答
1

您可以在一个 javascript 块中加载部分视图,该块的样式下降到头部,但考虑到您可能出于同样的原因希望在头部部分中使用 javascript 块,这将是愚蠢的。

不过,我最近发现了一些很酷的东西。您可以将部分视图序列化为字符串并将其作为 JSON 对象的一部分发送回客户端。这使您还可以与视图一起传递其他参数。

将视图作为 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);
     }
});
于 2010-11-18T00:15:20.260 回答
1

您可以使用 aHttpModule来操作响应 HTML 并将任何 CSS/脚本引用移动到适当的位置。这并不理想,而且我不确定性能影响,但它似乎是解决问题的唯一方法,无需 (a) 基于 javascript 的解决方案,或 (b) 违反 MVC 原则。

于 2010-11-18T23:48:42.083 回答
0

另一种违反 MVC 原则的方法是使用 ViewModel 并响应页面的 Init 事件来设置所需的 css/javascript(即 myViewModel.Css.Add(".css") 并在您的头部呈现viewmodel 上的 css-collection 的内容。

为此,您创建一个基础视图模型类,您的所有其他模型都继承自该类,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>
于 2010-11-18T12:41:50.583 回答
0

以下仅在启用 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 的情况下才对我有用,从而稍微限制了它的有用性。

于 2010-11-18T13:27:28.157 回答