Совместное использование ресурсов в разных модулях amd
В настоящее время я разрабатываю новое веб-приложение.
Это первый раз, когда я использую requirejs с модулями AMD.
Не так легко привыкнуть к этой новой парадигме, что, как я ее понимаю, нет переменных в глобальном пространстве имен.
В предыдущих веб-приложениях у меня всегда была одна переменная в глобальном пространстве имен, которую я мог использовать для совместного использования нескольких ресурсов в разных модулях.
Теперь с требованиями модулей AMD, я использую backbone.js и jquery (обе версии amd - jquery 1.7.1 и backbone.js 0.5.3-optamd3).
Где-то в моем приложении я получаю модуль backbone.js с сервера (объект пользователя). Я хотел бы иметь доступ к этому модулю из разных модулей AMD. Я также хочу иметь объект события с широким спектром приложений.
Не могли бы вы рассказать мне: какой правильный подход требует от AMD совместного использования ресурсов через разные модули?
Ответы
Ответ 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: {}
});
Достаточно.
Смотрите: документы
Будьте осторожны с этими вещами. Есть случаи, когда общие модули данных имеют смысл. Но если вы в конечном итоге используете его как псевдо-глобальное пространство имен, оно не намного лучше, чем просто использование глобальных переменных (не говоря о том, что вы делаете, хотя).