Pregunta

Actualmente estoy desarrollando una nueva aplicación web.

Esta es la primera vez que uso requeríajs con módulos AMD.

No es tan fácil acostumbrarse a ese nuevo paradigma que existen, según tengo entendido, sin variables en el espacio de nombres global.

En aplicaciones web anteriores, siempre tuve una variable en el espacio de nombres global que podría usar para compartir varios recursos en diferentes módulos.

Ahora con los módulos AMD Requirjs, uso BackBone.js y JQuery (ambas versiones AMD - JQuery 1.7.1 y Backbone.js 0.5.3 -Optamd3).

En algún lugar de mi aplicación, obtengo un módulo Backbone.js del servidor (objeto de usuario). Me gustaría tener acceso a este módulo desde diferentes módulos AMD. También quiero tener un objeto de evento amplio para la aplicación.

¿Podría decirme: ¿Cuál es la forma correcta en Requirjs AMD para compartir recursos en diferentes módulos?

¿Fue útil?

Solución

Encontré una solución yo mismo.

Gracias, intientalide, por su respuesta, pero esperaba una solución similar a la AMD. Esto significa, no de nuevo, "contaminar" el espacio de nombres global.

Había 2 claves para mi solución:

"https://github.com/addyosmani/backbone-aura"De Addy Osmani y"https://github.com/amdjs/amdjs-api/wiki/amd"La especificación API de definición del módulo asíncrono (AMD).

La especificación dice: "Si la fábrica es una función, solo debe ejecutarse una vez".

Entonces, si un módulo AMD se especifica varias veces como una dependencia en una aplicación web, la dependencia no es solo No cargado varias veces, tambien es No ejecutado varias veces, y esto es lo nuevo para mí. Solo se ejecuta una vez y se mantiene el valor de retorno de la función de fábrica. Cada dependencia con la misma ruta tiene el mismo objeto. Y esto lo cambia todo.

Entonces, simplemente defina el siguiente módulo AMD:

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

Ahora, en aquellos módulos donde desea compartir recursos, declara este módulo APP_REGISTERS como dependencia y escribe en uno:

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;
    }
    ...

y en el otro:

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. ...
    }
    ...

Otros consejos

Para responder a su pregunta sobre cómo proporcionar un objeto de evento amplio para la aplicación, puede crear un módulo AMD llamado GlobalContext e instanciarlo en Main.js.
A partir de entonces, puede adjuntar configuraciones al GlobalContext y usar el contexto global para crear subcomponentes, etc.

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

En el archivo global-context.js podemos realizar tareas como la carga de módulos infantiles

    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);
};

Esto es lo que hemos implementado en Boilerplatejs, una arquitectura de referencia para el desarrollo de productos JavaScript a gran escala.

Puede usar el patrón de inicialización para inyectar cualquier valor en un módulo requirador (también conocido como 'inyección de dependencia').

Haga una llamada requerida en cualquier lugar de su código:

var MyBackboneModule;

MyBackboneModule = someWayToGetAReferenceToIt();

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

Con el archivo módulo.js definido como

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

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

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


   return { 
      initialize: initialize
   };
});

Puedes definir un solo global APP En su punto de entrada módulo AMD. APP podría crear y mantener una referencia a otros módulos compartidos:

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

Solo un comentario sobre su propia respuesta: no necesita definir una función en su módulo App_registry:

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

Debería ser suficiente.

Ver: los documentos

Sin embargo, tenga cuidado con estas cosas. Hay USECases donde los módulos de datos compartidos tienen sentido. Pero si terminas usándolo como un espacio de nombres pseudo global, no es mucho mejor que solo usar globals (sin decir que eso es lo que estás haciendo).

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top