Обмен ресурсами в разных модулях AMD
-
27-10-2019 - |
Вопрос
В настоящее время я разрабатываю новое веб -приложение.
Это первый раз, когда я использую requirejs с модулями AMD.
Не так легко привыкнуть к этой новой парадигме, которая есть - насколько я понимаю - никаких переменных в глобальном пространстве имен.
В предыдущих веб -приложениях у меня всегда была одна переменная в глобальном пространстве имен, которую я мог бы использовать для обмена несколькими ресурсами в разных модулях.
Теперь с модулями requirejs amd я использую Backbone.js и jQuery (обе версии AMD - jQuery 1.7.1 и Backbone.js 0.5.3 -optamd3).
Где -то в моем приложении я получаю модуль Backbone.js с сервера (пользовательский объект). Я хотел бы иметь доступ к этому модулю из разных модулей AMD. Я также хочу иметь объект события с широким приложением.
Не могли бы вы сказать мне: как правильный путь в TreadJs Amd обмениваться ресурсами в разных модулях?
Решение
Я сам нашел решение.
Спасибо, Intothevoid, за ваш ответ, но я надеялся на AMD-подобное решение. Это означает, не снова «загрязняет» глобальное пространство имен.
В моем решении было 2 ключа:
"https://github.com/addyosmani/backbone-aura"От Адди Османи и"https://github.com/amdjs/amdjs-api/wiki/amd"Спецификация API определения асинхронного модуля (AMD).
Спецификация гласит: «Если фабрика является функцией, ее следует выполнять только один раз».
Таким образом, если модуль AMD указывается несколько раз в качестве зависимости в веб -приложении, зависимость не только Не загружается несколько раз, это также Не выполняется несколько раз, и это новая вещь для меня. Он выполняется только один раз, и возвращаемое значение заводской функции сохраняется. Каждая зависимость с одним и тем же путем имеет одинаковый объект. И это все меняет.
Итак, вы просто определяете следующий модуль AMD:
define([], function() {
var app_registry = {};
app_registry.global_event_obj = _.extend({}, Backbone.Events);
app_registry.models = {};
return app_registry;
});
Теперь, в тех модулях, где вы хотите поделиться ресурсами, вы объявляете этот модуль APP_REGISTRE как зависимость и пишете в одном:
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. ...
}
...
Другие советы
Чтобы ответить на ваш вопрос о том, как предоставить объект события с широким приложением, вы можете создать модуль 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);
};
Это то, что мы реализовали в Coalerplatejs, справочная архитектура для крупномасштабной разработки продукта JavaScript.
Вы можете использовать шаблон инициализации для введения любого значения в модуль 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
};
});
Вы можете определить один глобальный APP
В вашей точке входа AMD модуль. APP
может создать и сохранить ссылку на другие общие модули:
APP = {
this.settings : function() {
if(settingsModule == undefined){
//require, create and return it
} else {
return settingsModule;
}
}
}
Просто комментарий к своему собственному ответу - вам не нужно определять функцию в своем модуле APP_REGISTE:
define({
global_event_obj: _.extend({}, Backbone.Events);
models: {}
});
Должно быть достаточно.
Видеть: Документы
Будьте осторожны с этими вещами, хотя. Есть использование, где общие модули данных имеют смысл. Но если вы в конечном итоге используете его в качестве псевдо глобального пространства имен, это не намного лучше, чем просто использовать глобалов (не говоря уже о том, что вы делаете).