Pergunta

Existe uma maneira de adicionar referências de CSS a uma página de uma visão parcial, e faça com que eles renderizem na página <head> (conforme exigido pelo HTML 4.01 Spec)?

Foi útil?

Solução 4

Você pode usar um HttpModule Para manipular a resposta HTML e mover quaisquer referências de CSS/Script para os locais apropriados. Isso não é o ideal e não tenho certeza das implicações de desempenho, mas parece que a única maneira de resolver o problema sem (a) uma solução baseada em JavaScript ou (b) trabalhando contra os princípios do MVC.

Outras dicas

Se você estiver usando o MVC3 & RAZOR, a melhor maneira de adicionar itens por página à sua seção é: 1) CHAMADA RENESECTION () De dentro do seu layout Página 2) Declare uma seção correspondente nas páginas da sua criança:

/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" />
}

A página HTML resultante inclui uma seção que se parece com a seguinte:

<head>
    <!-- ... Rest of your head section here ... ->
    <link rel="Stylesheet" type="text/css" href="/Entries/Entries.css" />
<head>

Você também pode usar os controles de código aberto Telerik para MVC e fazer algo como:

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

na seção da cabeça e

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

Na seção de scripts no garrafa da sua página.

E você pode continuar adicionando scripts em qualquer visualização ou visualização parcial e eles devem funcionar.

Se você não deseja usar o componente, sempre pode se inspirar a partir daí e fazer algo mais personalizado.

Ah, com o Telerik, você também tem opções de combinação e compactação dos scripts.

Você pode ter a carga parcial de visualização em um bloco JavaScript que cai no estilo na cabeça, mas isso seria bobo, considerando que você provavelmente deseja o bloco JavaScript na seção da cabeça pelo mesmo motivo.

Recentemente, descobri algo muito legal. Você pode serializar uma exibição parcial em uma string e enviá -la de volta ao cliente como parte de um objeto JSON. Isso permite que você passe outros parâmetros também, junto com a vista.

Retornando uma visão como parte de um objeto JSON

Você pode pegar um objeto JSON com JQuery e Ajax e carregá -lo com a visualização parcial, e depois outra propriedade JSON pode ser o seu bloco de estilo. O jQuery pode verificar se você retornou um bloco de estilo, se assim for, solte -o na seção da cabeça.

Algo como:

$.ajax(
{
     url: "your/action/method",
     data: { some: data },
     success: function(response)
     {
          $('#partialViewContainer).html(response.partialView);
          if (response.styleBlock != null)
               $('head').append(response.styleBlock);
     }
});

Outra abordagem, que derrota os princípios do MVC, é usar um viewmodel e responder ao evento init-e de sua página para definir o CSS/JavaScript desejado (ou seja, myviewmodel.css.add (". CSS") e em sua cabeça renderizar o Conteúdo da coleta CSS no seu ViewModel.

Para fazer isso, você cria uma classe Base ViewModel que todos os seus outros modelos herdam, ala

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

Na sua página mestre, você o define para usar este viewmodel

<%@ Master Language="C#" Inherits="System.Web.Mvc.ViewMasterPage<BaseViewModel>" %>

E sua seção na cabeça você pode escrever o valor da propriedade 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>

Agora, em sua visão parcial, você precisa ter esse código, o que é meio feio no MVC

<script runat="server">
    protected override void OnInit(EventArgs e)
    {
        Model.Css = "hej";

        base.OnInit(e);
    }
</script>

O seguinte funcionaria apenas se o JavaScript fosse ativado. É um ajudante que eu uso exatamente para o cenário que você menciona:

// 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());
}

uso:

<%=Html.Css("~/content/site.css", true) %>

Funciona para mim, como afirmado, somente se o JavaScript estiver ativado, limitando assim um pouco a utilidade.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top