代码之家  ›  专栏  ›  技术社区  ›  kristian

从部分视图向页面的<head>添加CSS引用

  •  11
  • kristian  · 技术社区  · 14 年前

    有没有办法从部分视图向页面添加CSS引用, 让他们在页面的 <head> (根据 HTML 4.01 spec )?

    6 回复  |  直到 14 年前
        1
  •  5
  •   Rich Turner    13 年前

    如果您使用的是MVC3&Razor,将每页项目添加到您的部分的最佳方法是: 1) 从布局页中调用RenderSection() 2) 在子页中声明相应的节:

    /视图/Shared/\u Layout.cshtml:

    <head>
        <!-- ... Rest of your head section here ... ->
        @RenderSection("HeadArea")
    </head>
    

    /视图/条目/索引.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>
    
        2
  •  4
  •   sirrocco    14 年前

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

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

    头部部分 和

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

    在页面底部的脚本部分。

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

    如果你不想使用这个组件,你可以从中得到启发,做一些更定制的事情。

    哦,有了Telerik,你还可以选择组合和压缩脚本。

        3
  •  1
  •   Community Dai    7 年前

    您可以在javascript块中加载部分视图,将样式放到head中,但考虑到您可能出于相同的原因而希望javascript块位于head部分,这将是愚蠢的。

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

    Returning a view as part of a JSON object

    您可以使用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);
         }
    });
    
        4
  •  1
  •   kristian    14 年前

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

        5
  •  0
  •   Pauli Østerø    14 年前

    另一种违背MVC原则的方法是使用ViewModel并响应页面的Init事件来设置所需的css/javascript(即myViewModel.css.Add(“.css”),然后在头部呈现ViewModel上css集合的内容。

    为此,您将创建一个基本viewmodel类,所有其他模型都从该类继承,ala

    public class BaseViewModel
    {
        public string Css { get; set; }
    }
    

    在母版页中,将其设置为使用此viewmodel

    <%@ 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>
    
        6
  •  0
  •   jim tollan    14 年前

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