web-dev-qa-db-ja.com

JavaScriptファイルを部分ビューに含める

Javascriptファイルを部分ビューに含めるためのベストプラクティスは何だと思いますか。レンダリングすると、これはページのhtmlの中央にjs includeタグとして配置されます。私の観点からすると、これはこれを行う良い方法ではありません。これらはheadタグに属しているため、ブラウザが一度にhtmlをレンダリングするのを妨げてはなりません。

例:「PictureGallery」部分ビュー内でjquery picturegalleryプラグインを使用しています。この部分ビューは複数のページで使用されるためです。このプラグインは、このビューが使用されている場合にのみロードする必要があります各部分ビューが使用しているプラ​​グインを知る必要はありません...

ご回答ありがとうございます。

69
Peter

この質問に非常によく似ているようです: ユーザーコントロールのJavaScriptライブラリのリンク

その質問に対する答えをここに再投稿します。

あなたが言及したとおりの理由で、それらをパーシャルに入れることは絶対にお勧めします。 1つのビューが、同じjsファイルへの参照を持つ2つのパーシャルを取り込む可能性が高くなります。また、残りのhtmlをロードする前にjsをロードするとパフォーマンスが低下します。

ベストプラクティスについてはわかりませんが、マスターページ内に一般的なjsファイルを含め、特定のビューまたは少数のビューに固有の追加のjsファイル用に別個のContentPlaceHolderを定義することを選択します。

マスターページの例を次に示します-自明です。

<%@ Master Language="C#" Inherits="System.Web.Mvc.ViewMasterPage" %>
<head runat="server">
    ... BLAH ...
    <asp:ContentPlaceHolder ID="AdditionalHead" runat="server" />
    ... BLAH ...
    <%= Html.CSSBlock("/styles/site.css") %>
    <%= Html.CSSBlock("/styles/ie6.css", 6) %>
    <%= Html.CSSBlock("/styles/ie7.css", 7) %>
    <asp:ContentPlaceHolder ID="AdditionalCSS" runat="server" />
</head>
<body>
    ... BLAH ...
    <%= Html.JSBlock("/scripts/jquery-1.3.2.js", "/scripts/jquery-1.3.2.min.js") %>
    <%= Html.JSBlock("/scripts/global.js", "/scripts/global.min.js") %>
    <asp:ContentPlaceHolder ID="AdditionalJS" runat="server" />
</body>

Html.CSSBlockとHtml.JSBlockは明らかに私自身の拡張ですが、繰り返しますが、何をするかは自明です。

次に、SignUp.aspxビューで言うと

<asp:Content ID="signUpContent" ContentPlaceHolderID="AdditionalJS" runat="server">
    <%= Html.JSBlock("/scripts/pages/account.signup.js", "/scripts/pages/account.signup.min.js") %>
</asp:Content>

HTH、チャールズ

追伸これは、jsファイルの縮小と連結について尋ねたフォローアップの質問です。 オンザフライでJSを連結および縮小しますOR-ASP.NET MVC

EDIT:私の他の答えで要求されたように、要求された.JSBlock(a、b)の実装

public static MvcHtmlString JSBlock(this HtmlHelper html, string fileName)
{
    return html.JSBlock(fileName, string.Empty);
}

public static MvcHtmlString JSBlock(this HtmlHelper html, string fileName, string releaseFileName)
{
    if (string.IsNullOrEmpty(fileName))
        throw new ArgumentNullException("fileName");

    string jsTag = string.Format("<script type=\"text/javascript\" src=\"{0}\"></script>",
                                 html.MEDebugReleaseString(fileName, releaseFileName));

    return MvcHtmlString.Create(jsTag);
}

そして、魔法が起こる場所...

    public static MvcHtmlString MEDebugReleaseString(this HtmlHelper html, string debugString, string releaseString)
    {
        string toReturn = debugString;
#if DEBUG
#else
        if (!string.IsNullOrEmpty(releaseString))
            toReturn = releaseString;
#endif
        return MvcHtmlString.Create(toReturn);
    }
28
Charlino

今日は、法案に完全に適合する独自のソリューションを作成しました。良いデザインであるかどうかにかかわらず、あなたが決めるのはあなたですが、私はどちらの方法でも共有すべきだと考えました!

以下は、マスターページでこれを行うことができるHtmlExtensionsクラスです。

_<%=Html.RenderJScripts() %>
_

私のHtmlExtensionsクラス:

_public static class HtmlExtensions
{
    private const string JSCRIPT_VIEWDATA = "__js";

    #region Javascript Inclusions

    public static void JScript(this HtmlHelper html, string scriptLocation)
    {
        html.JScript(scriptLocation, string.Empty);
    }

    public static void JScript(this HtmlHelper html, string scriptLocationDebug, string scriptLocationRelease)
    {
        if (string.IsNullOrEmpty(scriptLocationDebug))
            throw new ArgumentNullException("fileName");

        string jsTag = "<script type=\"text/javascript\" src=\"{0}\"></script>";

#if DEBUG
        jsTag = string.Format(jsTag, scriptLocationDebug);
#else
        jsTag = string.Format(jsTag, !string.IsNullOrEmpty(scriptLocationRelease) ? scriptLocationRelease : scriptLocationDebug);
#endif

        registerJScript(html, jsTag);
    }

    public static MvcHtmlString RenderJScripts(this HtmlHelper html)
    {
        List<string> jscripts = html.ViewContext.TempData[JSCRIPT_VIEWDATA] as List<string>;
        string result = string.Empty; ;
        if(jscripts != null)
        {
            result = string.Join("\r\n", jscripts);
        }
        return MvcHtmlString.Create(result);
    }

    private static void registerJScript(HtmlHelper html, string jsTag)
    {
        List<string> jscripts = html.ViewContext.TempData[JSCRIPT_VIEWDATA] as List<string>;
        if(jscripts == null) jscripts = new List<string>();

        if(!jscripts.Contains(jsTag))
            jscripts.Add(jsTag);

        html.ViewContext.TempData[JSCRIPT_VIEWDATA] = jscripts;
    }

    #endregion

}
_

何が起こっているのですか?
上記のクラスは、HtmlHelperをメソッドで拡張して、_HtmlHelper.ViewContext.TempData_コレクションによって保存されているコレクションにjavascriptリンクを追加します。マスターページの最後に、<%=Html.RenderJScripts() %>を配置し、jscriptsコレクションを_HtmlHelper.ViewContext.TempData_内でループし、これらを出力にレンダリングします。

ただし、欠点があります。スクリプトを追加する前に、レンダリングしないようにする必要があります。たとえば、cssリンクに対してこれを行いたい場合は、これらをページの_<head>_タグに配置する必要があり、htmlhelperが出力を追加する前に出力をレンダリングするため、機能しません。リンク。

1
Peter

ページの下部にスクリプトを配置する理由は、操作を試みる前にdomがロードされていることを確認するためです。これは、$(document).ready(callback);のようなものでも実現できます。 jQueryメソッド。

埋め込みJavaScriptをHTMLに入れないという見解を共有します。代わりに、Htmlヘルパーを使用して、空のdivを作成し、サーバー命令として使用します。ヘルパーsigはHtml.ServerData(String name、Object data)です。

サーバーからクライアントへの指示には、このServerDataメソッドを使用します。 divタグはそれをクリーンに保ち、「data-」属性は有効なhtml5です。

LoadScript命令の場合、ascxまたはaspxで次のようなことを行います。

 <%= Html.ServerData( "loadScript"、new {url: "pathTo.js"})%> 

または、これを行うために別のヘルパーを追加します。これは少しきれいに見えます。

<%= Html.LoadScript( "〜/ path/to.js")%>

Html出力は次のようになります。

<div name = "loadScript" data-server = "encoded json string">

次に、任意のサーバーデータタグを見つけることができるjQueryメソッドがあります。$(含むElement).serverData( "loadScript"); //デコードされたjsonオブジェクトの配列のようなjQueryを返します。

クライアントは次のようになります。

 var script = $(含む要素 ").serverData(" loadScript "); 
 $。getScript(script.url、function(){
 //スクリプトがロードされました-今それで何かをすることができます
}); 

この手法は、ajaxで読み込まれたコンテンツ内に読み込む必要があるユーザーコントロールまたはスクリプトに最適です。私が書いたバージョンは、ページ全体の読み込みごとに1回だけ読み込み、コールバックとjQueryトリガーを含むため、準備ができたときにそれをフックできるように、キャッシングスクリプトの処理にもう少し関与します。

誰もがこの完全版(MVCからjQuery拡張機能まで)に興味がある場合は、この手法をさらに詳しくお見せできることを嬉しく思います。そうでなければ-それは誰かがこのトリッキーな問題にアプローチする新しい方法を提供することを望みます。

1
jhorback

ヘジッヒ。

Aspnetmvc3をいじって、今のところ、パーシャルにjavascriptファイルを含めることにしました

<script src = "@ Url.Content("〜/ Scripts/User/List.js ")" type = "text/javascript"> </ script>

このjsファイルは/user/List.schtmlファイルに固有です。

/の

0
LosManos

これは同様の質問のように思えます(完全ではありませんが)。 javascriptを含む部分ビューを返すのは悪い習慣ですか?

0
Allen Rice

私の好みは、メインのSite.masterを継承するplugin.masterページを作成することです。これらのプラグインをplugin.masterに詰め込み、この部分ビューを使用してplugin.masterから継承する8個程度のページを作成するという考え方です。

0
Pita.O

推奨されるアプローチは スクリプトを一番下に置く ですが、それを避けられない場合は、中間に置くのが妥当です。

通常、ブラウザはさまざまなページ要素を並行してロードしますが、ブラウザがJavascriptファイルをダウンロードしている間は、JavaScriptのダウンロードが完了するまで他のページ要素を並行してダウンロードしません。これは、あなたの画像と待たなければならないものが下にあるスクリプトを移動する方が一般に良いと考えられていることを意味しますが、スクリプトが小さい場合は心配しません。

0
aleemb