Есть ли способ добавить ссылки CSS на страницу из частичного просмотра, и отобразить их в <head>
страницы (в соответствии с требованиями спецификация HTML 4.01)?
Добавить ссылки CSS на ‹head› страницы из частичного просмотра
Ответы (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>
_Layout.cshtml
- это макет, а не частичное представление (то есть для экземпляров, включенных в Index.cshtml
, и он хочет правильно отобразить сценарий в тег <head>
_layout.cshtml
.
- person Shimmy Weitzhandler; 13.11.2012
@RenderSection("HeadArea", required:false)
в _Layout.cshtml
.
- person Leonard AB; 15.05.2019
Вы также можете использовать элементы управления Telerik с открытым исходным кодом для MVC и сделать что-то вроде:
<%= Html.Telerik().StyleSheetRegistrar()
.DefaultGroup(group => group
.Add("stylesheet.css"));
в головной части и
<%= Html.Telerik().ScriptRegistrar()
.DefaultGroup(group => group
.Add("script.js"));
в разделе скриптов внизу вашей страницы.
И вы можете продолжать добавлять сценарии в любое представление или частичное представление, и они должны работать.
Если вы не хотите использовать компонент, вы всегда можете вдохновить себя оттуда и сделать что-то более индивидуальное.
О, с Telerik у вас также есть возможности комбинирования и сжатия скриптов.
У вас может быть частичная загрузка представления в блоке javascript, который опускается в стиле до головы, но это было бы глупо, учитывая, что вы, вероятно, хотите, чтобы блок javascript в разделе заголовка по той же причине.
Однако недавно я обнаружил кое-что довольно крутое. Вы можете сериализовать частичное представление в строку и отправить его обратно клиенту как часть объекта JSON. Это позволяет вам передавать вместе с представлением и другие параметры.
Возврат представления как части объекта JSON
Вы можете захватить объект JSON с помощью JQuery и ajax и загрузить его с частичным представлением, и тогда другое свойство JSON может быть вашим блоком стиля. JQuery может проверить, вернули ли вы блок стиля, если да, то поместите его в раздел заголовка.
Что-то типа:
$.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 / скриптов в соответствующие места. Это не идеально, и я не уверен в последствиях для производительности, но кажется, что это единственный способ решить проблему без (а) решения на основе javascript или (б) работы против принципов MVC.
Другой подход, который противоречит принципам MVC, заключается в использовании ViewModel и ответе на событие Init на вашей странице для установки желаемого css / javascript (т.е. myViewModel.Css.Add (". Css") и визуализации в вашей голове содержимое css-коллекции на вашей модели просмотра.
Для этого вы создаете базовый класс модели представления, от которого наследуются все ваши модели, аля
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, что немного ограничивает его полезность.