2011-02-02 2 views
62

J'ai un certain nombre de "classes" JavaScript implémentées chacune dans son propre fichier JavaScript. Pour le développement, ces fichiers sont chargés individuellement, et pour la production ils sont concaténés, mais dans les deux cas je dois définir manuellement un ordre de chargement, en vérifiant que B vient après A si B utilise A. Je prévois d'utiliser RequireJS comme implémentation de CommonJS Modules/AsynchronousDefinition pour résoudre ce problème pour moi automatiquement.RequireJS: Comment définir des modules contenant une seule "classe"?

Existe-t-il une meilleure façon de procéder que de définir des modules qui exportent chacun une classe? Si non, comment nommer ce que le module exporte? Un module "employé" exportant une classe "Employé", comme dans l'exemple ci-dessous, ne me semble pas assez DRY.

define("employee", ["exports"], function(exports) { 
    exports.Employee = function(first, last) { 
     this.first = first; 
     this.last = last; 
    }; 
}); 

define("main", ["employee"], function (employee) { 
    var john = new employee.Employee("John", "Smith"); 
}); 

Répondre

108

Le AMD proposal vous permet de renvoyer une valeur pour l'objet exporté. Mais notez que c'est une caractéristique de la proposition d'AMD, c'est juste une proposition d'API, et il sera plus difficile de traduire le module en un module CommonJS régulier. Je pense que c'est OK, mais des informations utiles à connaître.

Vous pouvez donc effectuer les opérations suivantes:

Je préfère les modules qui exportent une fonction constructeur pour commencer avec un nom majuscule, de sorte que la version non optimisée de ce module serait également dans Employee.js

define("Employee", function() { 
    //You can name this function here, 
    //which can help in debuggers but 
    //has no impact on the module name. 
    return function Employee(first, last) { 
     this.first = first; 
     this.last = last; 
    }; 
}); 

maintenant dans un autre module, vous pouvez utiliser le module employé comme ceci:

define("main", ["Employee"], function (Employee) { 
    var john = new Employee("John", "Smith"); 
}); 
+0

Wow, une réponse directement de @jrburke, mr. Exige lui-même! +1! – Bart

98

en complément à la réponse de jrburke, notez que vous ne devez pas retourner le c fonction onstructor directement. Pour les classes les plus utiles que vous aurez également à ajouter des méthodes via le prototype, que vous pouvez faire comme ceci:

define('Employee', function() { 
    // Start with the constructor 
    function Employee(firstName, lastName) { 
     this.firstName = firstName; 
     this.lastName = lastName; 
    } 

    // Now add methods 
    Employee.prototype.fullName = function() { 
     return this.firstName + ' ' + this.lastName; 
    }; 

    // etc. 

    // And now return the constructor function 
    return Employee; 
}); 

En fait, c'est exactement le schéma indiqué dans this example at requirejs.org.

+1

Salut Mark, votre message est exactement ce que je cherche. Sauf une chose. Est-il possible de définir des champs pour l'objet Employee qui ne font pas partie du constructeur? Par exemple, possédez la propriété position et la méthode positionToUpper, mais définissez en quelque sorte cette propriété non dans le constructeur employee = new Employee ('john', 'smith'); employee.position = 'manager'; alert (employee.positionToUpper()); –

+4

Alex, cet exemple m'a été utile, il est très bien documenté et peut probablement fournir les exemples que vous cherchez: https://gist.github.com/jonnyreeves/2474026 –

+0

@NathanPrather c'est une excellente référence - les commentaires ont aidé à traduire moi d'un fond de java – y3sh

Questions connexes