Asp.net

在 MVC5 中使用 java 腳本程式碼 - 放在哪裡

  • April 6, 2014

我有 MVC5 應用程序並且在視圖 index.cshtml 中我需要使用一些 java 腳本程式碼,目前我將腳本程式碼放在視圖中並且它工作正常。我的問題是我應該把這段程式碼放在哪裡(來自最佳實踐),我應該如何從視圖中引用它?請提供一個例子。

我在下面寫下的方法是我從您的視圖中完全提取 JavaScript 的方法。

  • 更好地維護(js問題->查看js文件而不是視圖)
  • 模組化方法
  • 清晰的分離
  • 通過設計更好地理解

在 HTML5 中,使用data屬性從Model. 這極大地有助於將變數從 MVC(您的視圖模型)移植到 javascript。這也允許您將 javaScript 儲存在單獨的文件中,就像您可能希望在 MVC 環境中一樣。

1.1 將 c# 綁定到 HTML

<div class="news" data-js-params="websiteName=@LocationWebsiteHelper.CurrentLocationWebsiteName()&languageName=@languageName&page=0&itemsPerPage=@Model.MaxNumberOfItems">

1.2 將數據轉換為對象字面量的 JS Helper 函式

雖然基於 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

您有幾個選項可以將腳本附加到您的視圖/頁面/塊:

  • 在 baselayout 中定義的部分(僅用於部分視圖,直接包含在 baselayout 中)
  • c# ClientResources(不是 MVC 中的最佳方法,但仍然可行,允許您將外部文件包含到部分視圖中 -> 視圖中)
  • 捆綁包(好的或縮小的和模組化的方法)

2.2.1 部分的baselayout設置

@RenderSection("AdditionalJS", false)

2.2.2 用法局部視圖

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

2.3.1 視圖中視圖的baselayout設置

@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>

引用自:https://stackoverflow.com/questions/22893246