Использование java script кода в MVC5 - куда его поместить

У меня есть приложение MVC5 и в представлении index.cshtml Мне нужно использовать некоторый код java script, в настоящее время я помещаю код script внутри представления и его работоспособность. Мой вопрос: где я должен поместить этот код (из лучшей практики) и как Я ссылаюсь на это с точки зрения? Пожалуйста, укажите пример.

Ответ 1

Подход, который я описал ниже, - это мой способ полностью извлечения JavaScript из ваших представлений.

  • лучше поддерживать (js issues → искать в js файлах, а не в представлениях)
  • модульный подход
  • четкое разделение
  • лучше понять по дизайну

В HTML5 используйте атрибут data для передачи переменных из Model. Это очень помогает при переносе переменных из MVC (ваша модель просмотра) в javascript. Это также позволяет сохранять javaScript в отдельных файлах, как вам хотелось бы, в среде MVC.

1.1 Связывание С# с HTML

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

1.2 Функции JS Helper для преобразования данных в литералы объектов

Хотя он построен на jQuery, я написал две небольшие функции, которые могут помочь переносить переменные запроса в объектные литералы и обратно. Я использую их во всех файлах 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 object

С учетом этих функций вы можете передать любую строку запроса, такую ​​как переменные, в литерал объекта.

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/module выглядит так:

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)
  • С# 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>

Ответ 2

Для этого лучше использовать 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>.

Ответ 3

Если у вас есть и шаблон HTML 5, на самом деле неважно, где вы размещаете код JavaScript. Если вы используете шаблон XHTML, вы должны поместить свой код в теги <head></head>.

Теперь с лучшими практиками, сейчас лучше всего поставить весь ваш JS-код непосредственно перед тегом закрытия </body>. Таким образом, вы убедитесь, что теги html-элементов анализируются браузером.

При переходе в производственную среду лучше всего объединить все ваши JS в один .js файл, а затем его минимизировать, таким образом у вас будет только небольшой js файл, который должен получить клиентский браузер.

Уменьшите свой код

Термин minify во внешнем коде (css/js) означает процесс, в котором вы обрезаете все ваши пробелы и разрывы строк, а также переменные области функции заменяете более коротким именем, обычно просто гласным.

function foo(someVar){
   return someVar;
}

когда значение minified заменяется на:

function foo(e){return e}

В MVC4 была функция Bundling and Minification, которая могла бы помочь вам в этом. В MVC5 я не уверен.

Дальнейшее чтение: http://www.asp.net/mvc/tutorials/mvc-4/bundling-and-minification