Правильно ли я создаю свой JavaScript, чтобы он соответствовал спецификациям AMD?

Я выполнил этот вопрос, чтобы начать использовать RequireJS, а также RequireJS jQuery Docs. Я не смог найти, как повторно использовать пакеты в одном файле или как структурировать сам файл. Следующий код работает должным образом и отображает текст на странице. Первая часть javascript создается автоматически. using-iis">подробности см. в этом вопросе.

Меня интересует метод инициализации AMDSpecs.js. Это кажется контрпродуктивным для спецификаций AMD. Если это так, нужно ли мне вызывать требование каждый раз, когда мне нужен jQuery? Надеюсь, я объяснил, что я имею в виду, пожалуйста, спросите, нужна ли вам дополнительная информация.

HTML

<div id="output"></div>

JavaScript

<script src="/MVCTesting/Scripts/ThirdParty/RequireJS/require.js"></script>
<script type="text/javascript">
     require( [ "/MVCTesting/Scripts/AMD/core.js" ], function() {
     require( ["jquery", "/MVCTesting/Scripts/AMD/views/jquery/AMDSpecs.js"],                 
        function($, pm) {
           if (pm != undefined && pm.init) {
              pm.init($);
           }
        });
     });
</script>

/*AMDSpecs.js*/
define(function () {
    //Do setup work here

    return {
        $: undefined,
        setupEvents: function () {
            $("#output").text("jQuery is working!");
        },
        init: function ($) {
            this.$ = $;

            require(["Views/JQuery/AMDSpecs"], function (specs) {
                specs.setupEvents();
            });
        }
    };
});

ОБНОВЛЕНИЕ

Вот мое рабочее решение после ответа Дональда со всем кодом. Обратите внимание, мне все еще нужно включить .js в имя модуля, но это значительно упрощает процесс.

HtmlExtension.cs

    /// <summary>
    /// An Html helper for Require.js
    /// </summary>
    /// <param name="helper"></param>
    /// <param name="module">Location of the main.js file.</param>
    /// <returns></returns>
    public static MvcHtmlString RequireJS(this HtmlHelper helper, string module)
    {
        const string jsLocation = "Scripts/AMD/";

        //Don't build require string if there is not an amd script
        if (!File.Exists(helper.ViewContext.HttpContext.Server.MapPath(
                    GetAbsolutePath(Path.Combine(jsLocation, module + ".js")))))
        {
            return null;
        }

        var require = new StringBuilder();

        require.AppendLine("    require( [\"" + GetAbsolutePath(jsLocation + module + ".js") + "\"], function(pm) {");
        require.AppendLine("        if (pm != undefined && pm.init) {");
        require.AppendLine("            pm.init();");
        require.AppendLine("        }");
        require.AppendLine("    });");

        return new MvcHtmlString(require.ToString());
    }

    /// <summary>
    /// Convert the path to work in IIS for MVC
    /// </summary>
    /// <param name="path"></param>
    /// <returns></returns>
    private static string GetAbsolutePath(string path)
    {
        return VirtualPathUtility.ToAbsolute("~/" + path);
    }

    /// <summary>
    /// Create the include for RequireJS based on the current page
    /// </summary>
    /// <param name="helper"></param>
    /// <returns></returns>
    public static MvcHtmlString ViewSpecificRequireJS(this HtmlHelper helper)
    {
        var action = helper.ViewContext.RouteData.Values["action"];
        var controller = helper.ViewContext.RouteData.Values["controller"];

        return helper.RequireJS(string.Format("views/{0}/{1}", controller, action));
    }

_Layout.cshtml (MVCTesting — это название моего проекта)

<script data-main="/MVCTesting/Scripts/AMD/core.js" src="~/Scripts/ThirdParty/RequireJS/require.js"></script>

AMDSpecs.js

define(["jquery"], function ($) {
    //Do setup work here

    return {
        setupEvents: function () {
            $("#output").text("jQuery is working!");
        },
        init: function () {
            this.setupEvents();
        }
    };
});

person JabberwockyDecompiler    schedule 24.01.2014    source источник


Ответы (1)


Нет, вы делаете это не совсем правильно. Ваш «основной» файл JavaScript, определенный атрибутом data-main (одного и единственного) тега <script>, должен запускать приложение. Все остальные файлы JavaScript должны представлять собой «модули», то есть наборы функций, относящихся к конкретным целям.

Обратите внимание, что я не понимаю, что делает ваше приложение, поэтому, надеюсь, следующий пример поможет вам хотя бы начать работу.

<сильный>1. Загрузите основной скрипт:

<script data-main="main" src="/MVCTesting/Scripts/ThirdParty/RequireJS/require.js"></script>

<сильный>2. «main.js» запускает приложение:

require(["AMDSpecs"], function(specs) {
  specs.init();
});

<сильный>3. Разбейте ваши сценарии на отдельные файлы, представляющие «модули». В этом случае ваши "AMDSpecs" являются модулем:

/* AMDSpecs.js */

define(["jquery"], function($) {
  // do setup work here

  return {
    setupEvents: function() {
      $("#output").text("jQuery is working!");
    },
    init: function() {
      this.setupEvents();
    }
  };

});

Обратите внимание, что бесполезно встраивать вызовы require в вызовы require, если нет причин для условной или ленивой загрузки скрипта.

P.S. Не используйте расширение «.js» при запросе скриптов — это делается автоматически RequireJS.

person Donald Taylor    schedule 24.01.2014
comment
Ах, лампочка. Это имеет гораздо больше смысла в AMDSpecs. Я также добавлю data-main, я сделал это с настройкой одной страницы, и это сработало хорошо, я следил за этот блог, чтобы заставить его работать с MVC. Не сказать, что правильно ;). - person JabberwockyDecompiler; 24.01.2014
comment
Я упомянул в своем обновлении, что мне нужно добавить .js. Нашел в апи этот абзац. RequireJS also assumes by default that all dependencies are scripts, so it does not expect to see a trailing ".js" suffix on module IDs. RequireJS will automatically add it when translating the module ID to a path.... Это, безусловно, то, что они говорят вам делать, и поначалу это очень сбивало с толку. На отдельных страницах я должен сделать это. Но мне пришлось добавить расширение с MVC. - person JabberwockyDecompiler; 24.01.2014
comment
Подозрительно, что нужно указывать расширение .js. Это было ловушкой для меня на раннем этапе, потому что, если бы я включил его, скрипт не был бы загружен. - person Donald Taylor; 31.01.2014