web-dev-qa-db-ja.com

MVC5でJavaスクリプトコードを使用する-どこに配置するか

MVC5アプリケーションがあり、ビューindex.cshtmlでJavaスクリプトコードを使用する必要があります。現在、スクリプトコードをビュー内に配置し、正常に機能しています。私の質問は、(ベストプラクティスから)このコードをどこに配置する必要があるか、およびビューからどのように参照する必要があるか?例を提供してください。

14
07_05_GuyT

以下に記したアプローチは、JavaScriptをビューから完全に抽出する方法です。

  • 維持する方が良い(jsの問題->ビューではなくjsファイルを見る)
  • モジュラーアプローチ
  • 明確な分離
  • 設計で理解する方が良い

HTML5では、data属性を使用して、Modelから変数を渡します。これは、MVC(ビューモデル)からJavaScriptへの変数の移植に非常に役立ちます。これにより、おそらくMVC環境で必要となるように、javaScriptを別のファイルに保存しておくこともできます。

1.1 c#をHTMLにバインドする

_<div class="news" data-js-params="[email protected]()&amp;languageName=@languageName&amp;page=0&amp;[email protected]">
_

1.2 JSヘルパー関数はデータをオブジェクトリテラルに変換します

JQueryに基づいて構築されていますが、クエリ文字列変数をオブジェクトリテラルに移植したり戻したりするのに役立つ2つの小さな関数を作成しました。私はjsファイル全体でこれらを使用しています:

_// @param (qs): a query string of key value pairs (without ?)
// @param (keyDelimiter): string : character between values and keys
// @param (valDelimiter): string : character between keys and values
// @return (obj): an object literal
// @example: key1=val1&key2=val2&key3=val3
convertQsToLiteral: function (qs, keyDelimiter, valDelimiter) {
    var arrParams, obj = {};

    if (qs && qs.length) {
        keyDelimiter = keyDelimiter || '&';
        valDelimiter = valDelimiter || '=';
        arrParams = qs.split(keyDelimiter);

        $.each(arrParams, function (i, pair) {
            var arrPair = pair.split(valDelimiter),
                key = arrPair[0],
                val = arrPair[1];
             obj[key] = val;
        });
    }
    return obj;
},

// @param (literal): an object literal key value paired of one level deep
// @param (keyDelimiter): string  character between values and keys
// @param (valDelimiter): string : character between keys and values
// @return (string): array string representation
// @example: { key1: val1, key2: val2, key3: val3 }
convertLiteralToQs: function (literal, keyDelimiter, valDelimiter) {
    var arrQs = [],
        arrPairs, key;

    keyDelimiter = keyDelimiter || '&';
    valDelimiter = valDelimiter || '=';

    for (key in literal) {
        if (literal.hasOwnProperty(key)) {
            arrPairs = [];
            arrPairs.Push(key, literal[key]);
            arrQs.Push(arrPairs.join(valDelimiter));
        }
    }

    return arrQs.join(keyDelimiter);
},
_

1.3 HTMLデータをjsオブジェクトリテラルに変換する

これらの関数を念頭に置いて、変数などのクエリ文字列をオブジェクトリテラルに渡すことができます。

_var dataParams = convertQsToLiteral($('.news').data('js-params')); // get data attr
var urlParams = convertQsToLiteral(window.location.search.substr(1)); // get url query string
_

1.4例:オブジェクトリテラルを拡張およびオーバーライドするJSモジュラーセットアップ

JQueryの$.extend()関数と組み合わせると、モジュラーアプローチでjavascriptオブジェクトをオーバーライドできるようになりました(すべてのクロージャーを考慮すると、jsファイル/モジュールは次のようになります)。

_window.ProjectName = (function($, projectname){
    // default object literal
    var cfg = {
        // your default options
        idea: 'great'
    };

    // @param (options): something like the cfg object
    projectname.Module = function (options) {

        this.settings = $.extend(true, {}, cfg, options); // deep copy
        this.init();

    };

    projectname.Module.prototype = {
        init: function(){
            this.idea = this.settings.idea;
            console.log(this.idea);
        }
    };

    return projectname;
}(window.jQuery, window.ProjectName));
_

1.5 jsモジュールの初期化

_var module = new ProjectName.Module({ idea: 'even better' });
_

2.1スクリプト/ cssをビューに追加する

スクリプトをビュー/ページ/ブロックに添付するためのいくつかのオプションがあります。

  • ベースレイアウトで定義されたセクション(部分ビューのみ、ベースレイアウトに直接含まれます)
  • c#ClientResources(MVCでの最善のアプローチではありませんが、それでも実行可能です。外部ファイルを部分ビューに含めることができます->ビュー内のビュー)
  • バンドル(適切または縮小化およびモジュール化アプローチ)

2.2.1セクションのベースレイアウト設定

_@RenderSection("AdditionalJS", false)
_

2.2.2使用法の部分ビュー

_@section AdditionalJS
{
    <script>
        var module = new ProjectName.Module({ idea: @Model.idea });
    </script>
}
_

2.3.1ビュー内のビューのベースレイアウト設定

_@Html.Raw(Html.RequiredClientResources(RenderingTags.Header))
_

2.3.2ビュー内の使用状況ビュー

_ClientResources.RequireScript("/Design/js/projectname.module.js").AtHeader();
_

2.4.1スクリプトのBundleConfigセットアップ

_/// <summary>
/// Register the Javascript bundles
/// Separated in libJs, projectJs and polyfillJs
/// </summary>
/// <param name="bundles"></param>
private static void RegisterScripts(BundleCollection bundles)
{
    // usage for libraries
    bundles.Add(new ScriptBundle(
            "~/bundles/libJs").Include(
            "~/Design/js/lib/*.js"
    ));

    // project object
    bundles.Add(new ScriptBundle(
            "~/bundles/projectJs").Include(
            "~/Design/js/project.dev.js",
            "~/Design/js/classes/*.js",
            "~/Design/js/components/*.js"
    ));

    // usage for browser support
    bundles.Add(new ScriptBundle(
            "~/bundles/polyfillJs").Include(
            "~/Design/js/polyfills/*.js"
    ));
}

/// <summary>
/// Render scripts inside conditional comments
/// http://stackoverflow.com/questions/12865939/mvc4-bundling-minification-with-ie-conditional-comments
/// </summary>
/// <param name="ie"></param>
/// <param name="paths"></param>
/// <returns></returns>
public static IHtmlString RenderConditionalScripts(string ie, params string[] paths)
{
    var tag = string.Format("<!--[if {0}]>{1}<![endif]-->", ie, Scripts.Render(paths));
    return new MvcHtmlString(tag);
}
_

2.4.2 baselayoutセットアップ

_...
<head>
    ...
    @BundleConfig.RenderConditionalScripts("lte IE 9", "~/bundles/polyfillJs")
    @Scripts.Render("~/bundles/libJs")
<head>
<body>
    ...
    @Scripts.Render("~/bundles/projectJs")        
</body>
_
12
Tim Vermaelen

これにはRazor _@section_を使用する方がよいでしょう。

レイアウト内:

_<html>
     <head>
          <title>My Title</title>
          .....
          @RenderSection("Scripts", false)
     </head>

     <body>
          @RenderBody
     </body>
</html>
_

あなたの見解:

_<div id="container">
      <h3>Welcome!</h3>
      ...
</div>

@section Scripts
{
    <script type="text/javascript">
        // your script goes here
    </script>
}
_

代わりに、_</body>_タグの直前に@RenderSection("Scripts")を配置することを好む人もいます。

7
haim770

HTML 5テンプレートがある場合は、JavaScriptコードをどこに配置してもかまいません。XHTMLテンプレートがある場合は、コードを<head></head>タグ内に配置する必要があります。

現在のベストプラクティスでは、すべてのJSコードを</body>終了タグの直前に配置するのがベストプラクティスです。このようにして、html要素タグがブラウザによって解析されていることを確認します。

本番環境に行くときは、すべてのJSを単一の.jsファイルに連結してから縮小するのが最善です。そうすることで、クライアントブラウザーがフェッチする必要のある小さなjsファイルだけができます。

コードを縮小する

フロントエンドコード(css/js)での縮小という用語は、すべてのスペースと改行をトリミングするプロセスを表します。また、関数スコープ変数は、通常は母音だけの短い名前に置き換えられます。

function foo(someVar){
   return someVar;
}

縮小された場合:

function foo(e){return e}

MVC4には、これを支援するバンドリングと縮小機能がありました。 MVC5では、よくわかりません。

さらに読む: http://www.asp.net/mvc/tutorials/mvc-4/bundling-and-minification

2
gpopoteur