部分ビューからページに CSS 参照を追加し、それらをページでレンダリングする方法はありますか ( <head>
HTML 4.01 仕様で必要とされる)。
6 に答える
MVC 用の Telerik オープン ソース コントロールを使用して、次のようなことを行うこともできます。
<%= Html.Telerik().StyleSheetRegistrar()
.DefaultGroup(group => group
.Add("stylesheet.css"));
ヘッドセクションと
<%= Html.Telerik().ScriptRegistrar()
.DefaultGroup(group => group
.Add("script.js"));
ページの下部にあるスクリプト セクションで。
また、任意のビューまたは部分ビューにスクリプトを追加し続けることができ、それらは機能するはずです。
コンポーネントを使用したくない場合は、いつでもそこからインスピレーションを得て、よりカスタマイズしたことを行うことができます。
ああ、Telerik では、スクリプトを組み合わせて圧縮するオプションもあります。
スタイルを head にドロップする javascript ブロックに部分的なビューをロードすることもできますが、同じ理由で head セクションに javascript ブロックが必要になる可能性があることを考えると、それはばかげています。
私は最近、かなりクールなものを発見しました。部分ビューを文字列にシリアル化し、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);
}
});
を使用しHttpModule
て応答 HTML を操作し、CSS/スクリプト参照を適切な場所に移動できます。これは理想的ではなく、パフォーマンスへの影響についてはわかりませんが、(a) JavaScript ベースのソリューション、または (b) MVC の原則に反する作業を行わずに問題を解決する唯一の方法のようです。
MVC の原則を無効にする別のアプローチは、ViewModel を使用し、ページの Init-event に応答して目的の css/javascript (つまり、myViewModel.Css.Add(".css")) を設定し、頭の中でビューモデルの css コレクションのコンテンツ。
これを行うには、他のすべてのモデルが継承する基本ビューモデル クラスを作成します。
public class BaseViewModel
{
public string Css { get; set; }
}
マスターページで、このビューモデルを使用するように設定します
<%@ Master Language="C#" Inherits="System.Web.Mvc.ViewMasterPage<BaseViewModel>" %>
そしてあなたのhead-sectionは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が有効になっている場合にのみ機能するため、その有用性が少し制限されます。