在MVC 5中使用javascript代码 - 在哪里放置它

时间:2014-04-06 11:14:48

标签: asp.net asp.net-mvc asp.net-mvc-3 asp.net-mvc-4 razor

我有MVC5应用程序,并在视图index.cshtml我需要使用 一些java脚本代码,目前我将脚本代码放在视图中并且工作正常。 我的问题是我应该在哪里放置这些代码(来自最佳实践)以及如何应用 我从视图中提到它?请提供一个例子。

3 个答案:

答案 0 :(得分:12)

我在下面写的方法是我从你的观点中完全提取JavaScript的方法。

  • 更好地维护(js问题 - >查看js文件,而不是查看视图)
  • 模块化方法
  • 明确分离
  • 更好地通过设计理解

在HTML5中,使用data属性传递Model中的变量。 这有助于将变量从MVC(您的viewmodel)移植到javascript。 这也允许您将javaScript保存在单独的文件中,就像您在MVC环境中所希望的那样。

1.1将c#绑定到HTML

<div class="news" data-js-params="websiteName=@LocationWebsiteHelper.CurrentLocationWebsiteName()&amp;languageName=@languageName&amp;page=0&amp;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中的最佳方法,但仍然可行,允许您将外部文件包含在局部视图中 - &gt;视图中的视图)
  • 捆绑(良好或缩小和模块化方法)

2.2.1基本布局设置

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

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

答案 1 :(得分:7)

你最好使用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>
}

有些人更愿意将@RenderSection("Scripts")放在</body>标记之前。

答案 2 :(得分:2)

如果您有HTML 5模板,那么放置JavaScript代码的位置并不重要。如果您使用的是XHTML模板,则应将代码放在<head></head>标记内。

现在有了最佳实践,现在最好的做法是将所有JS代码放在</body>结束标记之前。这样,您可以确保浏览器已解析您的html元素标记。

当进入生产环境时,最好的方法是将所有JS连接到一个.js文件中然后让它缩小,这样你就会得到一个客户端浏览器需要获取的小js文件。

缩小代码

前端代码中的minify一词(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