2012-07-16 3 views
2

Je suis un développeur d'ActionScript 3 qui fait ses premiers pas dans la création d'une application JavaScript à grande échelle. Donc, je comprends les modules et comprends que AMD est un bon modèle à utiliser. J'ai lu sur RequireJS et l'ai implémenté. Cependant, ce que je ne comprends toujours pas, c'est comment réaliser la communication entre les modules. Je comprends qu'il devrait y avoir une sorte de médiateur ... Je lis des articles et des messages et ne comprenait toujours pas comment l'implémenter simplement. Voici mon code, simplifié:À partir de RequireJS, communication entre les modules

main.js

require(["Player", "AssetsManager"], function (player, manager) { 
    player.loadXML(); 
}); 

Player.js

define(function() { 
    function parseXml(xml) 
    { 
     // NOW HERE IS THE PROBLEM -- how do I call AssetsManager from here??? 

     AssetsManager.queueDownload($(xml).find("prop").text()); 
    } 

    return { 
     loadXML: function() { 
      //FUNCTION TO LOAD THE XML HERE, WHEN LOADED CALL parseXml(xml) 
     } 

    } 

}); 

AssetsManager.js

define(function() { 
    var arrDownloadQueue = []; 

    return { 
     queueDownload: function(path) { 
      arrDownloadQueue.push(path); 
     } 
    } 
}); 

Toute aide "pour les nuls" sera appréciée :) Merci.

Répondre

1

Pour charger des modules à partir d'autres modules que vous define(), vous devez simplement définir le premier paramètre sous la forme d'un tableau, avec vos noms de module. Donc, disons, dans votre code, vous vouliez charger Player.js en AssetsManager.js, vous incluez simplement la chaîne Player dans le tableau.

Ceci est tout simplement possible parce que la mise en œuvre abstraite de define équivaut à require, seulement que le rappel est passé à define attend une valeur à retourner, et qu'il ajoutera un « module » à une liste de dépendances que vous pouvez charger.

AssetsManager.js

define(['Player'], function (player) { 
    //... Your code. 
}); 

Cependant, si je peux ajouter, je préfère l'utilisation de require à l'intérieur de la fonction de rappel est passé à define pour saisir la dépendance que vous voulez charger, au lieu de passer le paramètre au callback.

Alors, voici ma suggestion:

define(['Player'], function() { 
    var player = require('Player'); 
}); 

Et cela est parce qu'il est beaucoup plus en phase avec CommonJS.

Et voilà comment main.js ressemblerait formaté pour être plus CommonJS de l'environnement:

require(["Player", "AssetsManager"], function() { 
    var player = require('Player'); 
    var manager = require('AssetsManager'); 
    player.loadXML(); 
}); 

Mais la façon de faire les choses CommonJS est juste une préférence personnelle. Mon raisonnement pour cela est que l'ordre dans lequel vous entrez les noms de dépendances dans le tableau peut changer à tout moment, et je ne voudrais pas avoir à parcourir à la fois le tableau et la liste des paramètres.

Une autre raison de la mienne (bien que ce soit juste pédant), c'est que je viens du monde de Node.js, où les modules sont chargés via require().

Mais c'est à vous de décider.

+1

Oui, ça marche! C'est en fait simple, merci. – Light

0

(Ce serait une réponse à la réponse de skizeey, mais je n'ai pas assez réputation pour cela)

Une autre façon de résoudre ce problème sans tirer dans la dépendance AssetManager du joueur par besoin est de passer l'instance AssetManager que main.js a déjà autour. Une façon d'y parvenir pourrait être de faire en sorte que la fonction loadXML de Player accepte un paramètre AssetManager qui est ensuite passé à parseXml, qui l'utilise ensuite. Un autre moyen pourrait être que Player ait une variable pour contenir un AssetManager lu par parseXml. Il pourrait être réglé directement ou une fonction pour stocker un AssetManager dans la variable pourrait être utilisée, appelée say, setAssetManager. Cette dernière méthode a toutefois une importance supplémentaire - vous devez alors gérer le cas où cette variable n'est pas définie avant d'appeler loadXml. Ce concept est généralement appelé "injection de dépendance". Pour être clair, je ne vous conseille pas d'utiliser AMD pour le charger. Je voulais simplement vous fournir plus d'options; peut-être que cette technique peut vous être utile pour résoudre un autre problème, ou aider quelqu'un d'autre. :)

Questions connexes