1

正しく機能するために Javascript/CSS ファイルを含める必要がある部分ビューを作成したいと考えています。同じ部分ビューをページ内に複数回含めることができるため、部分ビュー HTML コンテンツ内に Javascript/CSS ファイルを埋め込むと、そのようなファイルは N 回埋め込まれます。そのようなファイルは一度だけ埋め込まれたいと思います。

また、このような部分ビューは、出力キャッシュを利用するためにメソッドを使用してレンダリングされているHtml.Actionため、Action メソッドが常に実行されるわけではありません。

私の考えは、部分ビュー内のjavascript/cssファイルを、そのような埋め込みを管理するコントローラーに登録し、ページのスクリプトセクションの下部の終了</body>タグの前に出力することでしたが、アクションがキャッシュされるため、そのようなコードの実行は保証されていませんが、キャッシュからロードできます。

そのようなシナリオのベスト プラクティスに関する提案はありますか?

4

1 に答える 1

2

2 つのカスタム ヘルパーを定義できます。

public static class HtmlExtensions
{
    public static IHtmlString RenderRegisteredScripts(this HtmlHelper htmlHelper)
    {
        var ctx = htmlHelper.ViewContext.HttpContext;
        var registeredScripts = ctx.Items["_scripts_"] as Stack<string>;
        if (registeredScripts == null || registeredScripts.Count < 1)
        {
            return null;
        }
        var sb = new StringBuilder();
        foreach (var script in registeredScripts)
        {
            var scriptBuilder = new TagBuilder("script");
            scriptBuilder.Attributes["type"] = "text/javascript";
            scriptBuilder.Attributes["src"] = script;
            sb.AppendLine(scriptBuilder.ToString(TagRenderMode.Normal));
        }
        return new HtmlString(sb.ToString());
    }

    public static void RegisterScript(this HtmlHelper htmlHelper, string script)
    {
        var ctx = htmlHelper.ViewContext.HttpContext;
        var urlHelper = new UrlHelper(htmlHelper.ViewContext.RequestContext);
        var registeredScripts = ctx.Items["_scripts_"] as Stack<string>;
        if (registeredScripts == null)
        {
            registeredScripts = new Stack<string>();
            ctx.Items["_scripts_"] = registeredScripts;
        }
        var src = urlHelper.Content(script);
        if (!registeredScripts.Contains(src))
        {
            registeredScripts.Push(src);
        }
    }
}

そして、最後にヘルパーを_Layout.cshtml呼び出す a があります。RenderRegisteredScripts

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>@ViewBag.Title</title>
    <link href="@Url.Content("~/Content/Site.css")" rel="stylesheet" type="text/css" />
</head>
<body>
    @RenderBody()
    <script src="@Url.Content("~/Scripts/jquery-1.7.1.min.js")" type="text/javascript"></script>
    @RenderSection("Scripts", required: false)
    @Html.RenderRegisteredScripts()
</body>
</html>

これで、パーシャルを何度でもレンダリングするビューを作成できます。

@for (int i = 0; i < 10; i++)
{
    @Html.Partial("_Foo")    
}

@Html.Action("Bar")

このパーシャル ( _Foo.cshtml)内でRegisterScriptヘルパーを使用して、このパーシャルの依存スクリプトを登録します。

@{Html.RegisterScript("~/scripts/foo.js");}

生成された HTML マークアップを見ると、スクリプトは 1 回だけ含まれています。

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title></title>
    <link href="/Content/Site.css" rel="stylesheet" type="text/css" />
</head>
<body>
    <script src="/Scripts/jquery-1.7.1.min.js" type="text/javascript"></script>
    <script src="/scripts/foo.js" type="text/javascript"></script>
</body>
</html>
于 2013-02-04T13:19:34.800 に答える