Question

Je développe actuellement une nouvelle application Web.

Ceci est la première fois que je utilise requirejs avec des modules AMD.

Il est pas facile de se habituer à ce nouveau paradigme qu'il ya - ce que je comprends -. Pas de variables dans l'espace de noms global

Dans les applications Web précédentes J'ai toujours eu une variable dans l'espace de noms global que je pourrais utiliser pour partager plusieurs ressources entre les différents modules.

Maintenant, avec requirejs AMD modules, j'utilise Backbone.js et jquery (les deux versions amd - jquery 1.7.1 et 0.5.3 Backbone.js-optamd3)

.

Quelque part dans mon application, je vais chercher un module Backbone.js à partir du serveur (objet utilisateur). Je voudrais avoir accès à ce module de différents modules d'AMD. Je veux aussi avoir une application large objet d'événement.

Pouvez-vous me dire: quelle est la bonne façon requirejs AMD de partager des ressources à travers différents modules

?
Était-ce utile?

La solution

Je me suis trouvé une solution.

Merci, IntoTheVoid, pour votre réponse, mais j'espérais une solution AMD semblable. Cela signifie, pas encore, "polluer" l'espace de noms global.

Il y avait 2 clés de ma solution:

" https://github.com/addyosmani/backbone-aura " de Addy Osmani et « https://github.com/amdjs/amdjs-api/wiki/AMD » la spécification API le module asynchrone Définition (AMD).

La spécification dit: «Si l'usine est une fonction, il ne doit être exécutée une fois »

Donc, si un module amd est spécifié plusieurs fois en tant que dépendance dans une application Web, la dépendance est non seulement PAS CHARGÉ DES TEMPS DE PLUSIEURS , il est également NON EFFECTUÉ PLUSIEURS FOIS , ce qui est la chose nouvelle pour moi. Il est exécutée une seule fois et la valeur de retour de la fonction d'usine est maintenue. Chaque dépendance avec le même chemin d'accès a le même objet. Et cela change tout.

Alors, vous définissez simplement le module amd suivant:

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

Maintenant, dans les modules où vous souhaitez partager des ressources, vous déclarez ce module app_registry comme la dépendance et à écrire dans un:

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

et dans l'autre:

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

Autres conseils

Pour répondre à votre question de la façon de fournir une application large objet d'événement, vous pouvez créer un module amd appelé globalContext et instancier dans le main.js.
Par la suite, vous pouvez associer les paramètres à l'globalContext et utiliser le contexte mondial pour créer des sous-composants, etc.

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

Dans le fichier global-context.js nous pouvons effectuer des tâches telles que les modules d'enfants de chargement

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

Voici ce que nous avons mis en place dans BoilerplateJS , une architecture de référence pour javascript à grande échelle de développement de produits.

On peut utiliser le modèle initialize pour injecter une valeur quelconque dans un module de requirejs (aka "d'injection de dépendance).

Faites un appel besoin partout dans votre code:

var MyBackboneModule;

MyBackboneModule = someWayToGetAReferenceToIt();

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

Avec fichier défini comme module.js

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

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

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


   return { 
      initialize: initialize
   };
});

Vous pouvez définir un seul APP global dans votre module d'AMD point d'entrée. APP pourrait créer et maintenir une référence à d'autres modules partagés:

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

Juste un commentaire sur votre réponse - vous n'avez pas besoin de définir une fonction dans votre module app_registry:

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

suffire devrait le faire.

Voir: la documentation

Soyez prudent avec ces choses cependant. Il y a usecases où les modules de données partagées du sens. Mais si vous finissez par l'utiliser comme un pseudo espace de noms global, ce n'est pas beaucoup mieux que d'utiliser simplement globals (ne dis pas que ce que vous faites bien).

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top