Подтвердить что ты не робот

Совместное использование ресурсов в разных модулях amd

В настоящее время я разрабатываю новое веб-приложение.

Это первый раз, когда я использую requirejs с модулями AMD.

Не так легко привыкнуть к этой новой парадигме, что, как я ее понимаю, нет переменных в глобальном пространстве имен.

В предыдущих веб-приложениях у меня всегда была одна переменная в глобальном пространстве имен, которую я мог использовать для совместного использования нескольких ресурсов в разных модулях.

Теперь с требованиями модулей AMD, я использую backbone.js и jquery (обе версии amd - jquery 1.7.1 и backbone.js 0.5.3-optamd3).

Где-то в моем приложении я получаю модуль backbone.js с сервера (объект пользователя). Я хотел бы иметь доступ к этому модулю из разных модулей AMD. Я также хочу иметь объект события с широким спектром приложений.

Не могли бы вы рассказать мне: какой правильный подход требует от AMD совместного использования ресурсов через разные модули?

4b9b3361

Ответ 1

Я нашел решение самостоятельно.

Спасибо, IntoTheVoid, за ваш ответ, но я надеялся на AMD-подобное решение. Это означает, что опять-таки "загрязнение" глобального пространства имен.

Для моего решения было 2 ключа:

" https://github.com/addyosmani/backbone-aura" от Адди Османи и " https://github.com/amdjs/amdjs-api/wiki/AMD" Спецификация API определения асинхронного модуля (AMD).

Спектр говорит: "Если factory - это функция, она должна выполняться только один раз".

Итак, если модуль amd задан несколько раз в качестве зависимости в веб-приложении, зависимость не только НЕ НАГРУЖЕНЫ МНОЖЕСТВЕННЫХ ВРЕМЕНИ, она также НЕ ВЫПОЛНИЛА НЕСКОЛЬКО ВРЕМЕНИ, и для меня это новое дело. Он выполняется только один раз и сохраняется возвращаемое значение функции factory. Каждая зависимость с одним и тем же путем имеет один и тот же объект. И это все меняет.

Итак, вы просто определяете следующий модуль amd:

define([], function() {
    var app_registry = {};
    app_registry.global_event_obj = _.extend({}, Backbone.Events);
    app_registry.models = {};
    return app_registry;
});

Теперь, в тех модулях, где вы хотите обмениваться ресурсами, вы объявляете этот модуль app_registry зависимым и записываете в одном:

define(['jquery','underscore','backbone','app_registry'], 
  function ($, _, Backbone, app_registry){
    var firstView = Backbone.View.extend({
    initialize: function() {
        _.bindAll (this, 'methodOne'); 
        this.model.bind ('change', this.methodOne);   
        this.model.fetch();
    },  
    methodOne: function() {
        app_registry.models.abc = this.model;
    }
    ...

а в другом:

define(['jquery','underscore','backbone','app_registry'], 
  function ($, _, Backbone, app_registry){
    var secondView = Backbone.View.extend({
    initialize: function() {
       _.bindAll (this, 'methodTwo'); 
        app_registry.global_event_obj.bind ('special', this.methodTwo);
    },  
    methodTwo: function() {
        app_registry. ...
    }
    ...

Ответ 2

Чтобы ответить на вопрос о том, как обеспечить объект событий широкого применения, вы можете создать модуль amd, называемый globalContext, и создать его в main.js.
После этого вы можете присоединить настройки к globalContext и использовать глобальный контекст для создания подкомпонентов и т.д.

    //main.js file
    require([ "./global-context" ], function( GlobalContext) {
             new GlobalContext();
    });

В файле global-context.js мы можем выполнять такие задачи, как загрузка дочерних модулей

    define(["Boiler", "./settings", "./modules/modules"], 
           function (Boiler, settings, modules) {
                  var GlobalContext = function () {

                //here we use a template javascript class called Boiler.Context
                var globalContext = new Boiler.Context("GlobalModule");

                //add settings to the context which can be obtained globally throughout                    the application
                globalContext.addSettings(settings);

                //here we load the sub modules of the global context
                globalContext.loadChildModules(modules);
};

Это то, что мы реализовали в BoilerplateJS, эталонной архитектуре для разработки крупномасштабных javascript-продуктов.

Ответ 3

Вы можете использовать шаблон инициализации для ввода любого значения в модуль requirejs (например, "инъекция зависимостей" ).

Требуется ли позвонить в любом месте вашего кода:

var MyBackboneModule;

MyBackboneModule = someWayToGetAReferenceToIt();

require("module", function(Module) { 
  Module.initialize(MyBackboneModule);
});

С файлом module.js, определенным как

define([], function(){
   var BackboneModuleDoingThisAndThat;

   function initialize(pBackboneModule) {
      BackboneModuleDoingThisAndThat = pBackboneModule ;
   };

   function doSomething() {
      var x = BackboneModuleDoingThisAndThat.computeThis(42);
   };


   return { 
      initialize: initialize
   };
});

Ответ 4

Вы можете определить единый глобальный APP в точке входа в модуль AMD. APP может создавать и удерживать ссылку на другие разделяемые модули:

APP = {
    this.settings : function() {
        if(settingsModule == undefined){
            //require, create and return it
        } else {
            return settingsModule;
        }
    }
}

Ответ 5

Просто комментируйте свой собственный ответ - вам не нужно определять функцию в вашем модуле app_registry:

define({
  global_event_obj: _.extend({}, Backbone.Events);
  models: {}
});

Достаточно.

Смотрите: документы

Будьте осторожны с этими вещами. Есть случаи, когда общие модули данных имеют смысл. Но если вы в конечном итоге используете его как псевдо-глобальное пространство имен, оно не намного лучше, чем просто использование глобальных переменных (не говоря о том, что вы делаете, хотя).