Adicione referências CSS ao de Page de uma visão parcial
-
25-09-2019 - |
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)?
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.